Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript type restriction based on another value – how to apply this restriction in an array

I wasn’t sure how to word this question. I have a scenario where I have an object. Key1 is the name, key2 is options. Options type depends on the value of name.

This works ok, thanks to:

export type Option1 = {
  one: string;
};

export type Option2 = {
  two: string;
};

export type Name = 'first' | 'second';

export type Options<TName extends Name> = TName extends 'first'
  ? Option1
  : TName extends 'second'
  ? Option2
  : never;

type Baz<TName extends Name> = { name: TName, opts: Options<TName> }

Now I wish to use this in an object.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

type MyObj = {
   foo: boolean,
   bar: string,
   baz: Baz[]
}

The goal is to do something like this:

const test: MyObj = {
   baz: [ { name: 'first': opts: .. }, { name: 'second': opts: .. }]
}

With it being all typed correctly. If name is ‘first’, then opts is typed to only have key one. However, MyObj complains that I need to pass in a generic type to Baz, which makes sense, but I’m not sure what or how. I tried type Baz<TName extends Name = Name> to default it, but this just makes all my values a union of all options, where opts is one and two keys.

How can i restrict this type?

>Solution :

You can achieve it in a very simple way using union type:

export type Option1 = {
  one: string;
};

export type Option2 = {
  two: string;
};

export type NameWithOptions =
  | { name: 'first'; opts: Option1[] }
  | { name: 'second'; opts: Option2[] };

type MyObj = {
  foo: boolean;
  bar: string;
  baz: NameWithOptions[];
};

const test: MyObj = {
  baz: [
    { name: 'first', opts: [{ one: 'one' }] },
    { name: 'second', opts: [{ two: 'two' }] },
  ],
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading