Skip to content Skip to sidebar Skip to footer

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?"