Sometimes you run into an issue where you want some autocomplete, but not total autocomplete. For instance, here, we have a React component, which takes in a prop, which is a size. And this size here can be either sm or xs.
export const Icon = (props: IconProps) => {
return <></>
}
const Comp1 = () => {
return (
<>
<Icon size="xs"></Icon>
<Icon size="something"></Icon>
</>
)
}
But imagine that we design an API where you can either pass in sm, xs, or any arbitrary value. What you might think is the right thing to do is to add string to the IconSize union type.
type IconSize = "sm" | "xs" | string
This seems to make sense, except that you lose all the autocomplete on the size prop, which isn't really what you want. The reason this happens is that TypeScript is quite clever with union types, and it tries to kind of pull in all of the types that it can.
For instance, if you specify the same type twice, like xs, then it won't show up twice in the autocomplete.
type IconSize = "sm" | "xs" | "xs"
The reason this is happening with a string, is that TypeScript is reasoning since xs and sm are both strings, and you're also specifying string, that it means it should just removed xs and sm and only offer string. Preventing your from getting autocomplete.
The way we can get around this is we can actually use the Omit utility type, and we can omit xs or sm from the union. And now TypeScript won't collapse. these three things, and you'll have autocomplete again.
type IconSize = "sm" | "xs" | Omit<string, "xs", "sm">
We can even turn this into a type helper if we want to.
type LooseAutocomplete<T extends string> = T | Omit<string, T>
This is a way of just taking this information up in our IconSize type and turning it into a type helper. And now we can just wrap sm and xs in this type helper.
type IconSize = LooseAutocomplete<"sm" | "xs">
And it's gonna work for us. So again, xs, sm, and any arbitrary value.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.