Skip to content

Instantly share code, notes, and snippets.

@danfoust
Created April 8, 2022 15:11
Show Gist options
  • Save danfoust/7c87ac47f50af9916983b40a7bf408a6 to your computer and use it in GitHub Desktop.
Save danfoust/7c87ac47f50af9916983b40a7bf408a6 to your computer and use it in GitHub Desktop.
Narrow string | number union with utility type
/*
If you try to do `keyof SomeType`, and `SomeType` has an interface of `[key: string]: x`
TypeScript will infer that to a union of `string | number` because JavaScript coerces numeric
indexes to strings.
Example: obj[0] -> obj["0"]
This can make it annoying to try to create an interface for interacting with one of these
types when we know we only want to accept string values, or that's a rule we want to enforce.
Below are some examples of how we can narrow the type to only be string values.
Reference: https://stackoverflow.com/q/51808160/7903952
*/
type MetaDefinition = {
name?: string;
content?: string;
} & {
[prop: string]: string;
}
// Approach 1 - Extract<> Utility type
type StringKeyOf<T> = Extract<keyof T, string>;
function getTagsBySelector(prop: StringKeyOf<MetaDefinition>): HTMLMetaElement[];
// Approach 2 - Create an Intersection type with `&`
function getTagsBySelector(prop: MetaDefinition & string): HTMLMetaElement[];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment