Restrict Property To Values Defined In Other Property's Object Array?
Given type Props= { defaultTab?: string; tabs?: { id: string; // ... }[]; }; I'd like to update the definition of defaultTab to restrict the possible values to those
Solution 1:
It's possible — but it requires a hack.
First, make your Props
generic. This is needed to establish a relationship between tabs
and defaultTab
.
typeProps<T extendsstring>= {
defaultTab?: T;
tabs?: {
id: T;
// ...
}[];
};
declareclassMyComponent<T extendsstring> extendsReact.Component<Props<T>> {};
We're not done yet. If you do:
<MyComponent tabs={[{ id: 'foo' }, { id: 'bar' }]} defaultTab="potato" />
it will compile because the allowed values for defaultTab
will include whatever we pass to defaultTab
! We need to tell TypeScript that defaultTab
should depend on whatever we have provided in tabs
. In other words, we want to tell TypeScript: first, look at tabs
. Only then infer what defaultTab
can be.
/**
* @see https://github.com/microsoft/TypeScript/issues/14829#issuecomment-504042546
*/typeDeferTypeInference<T> = [T][T extendsany ? 0 : never];
typeProps<T extendsstring>= {
defaultTab?: DeferTypeInference<T>;
tabs?: {
id: T;
// ...
}[];
};
declareclassMyComponent<T extendsstring> extendsReact.Component<Props<T>> {};
Now it works!
<MyComponent tabs={[{ id: 'foo' }, { id: 'bar' }]} defaultTab="bar" /> // OK
<MyComponent tabs={[{ id: 'foo' }, { id: 'bar' }]} defaultTab="potato" /> // Compile-time error
Post a Comment for "Restrict Property To Values Defined In Other Property's Object Array?"