Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

all possible keys of an union type

Tags:

typescript

I want to get all available keys of an union type.

interface Foo {
  foo: string;
}

interface Bar {
   bar: string;
}

type Batz = Foo | Bar;

type AvailableKeys = keyof Batz;

I want to have 'foo' | 'bar' as result of AvailableKeys but it is never (as alternative I could do keyof (Foo & Bar), what produces exact the required type but I want to avoid to repeat the Types).

I found already the issue keyof union type should produce union of keys at github. I understand the answer, that keyof UnionType should not produce all possible keys.

So my question is: Is there an other way to get the list of all possible keys (it is ok if the verison 2.8 of tsc is required)?

like image 783
Xenya Avatar asked Mar 21 '18 08:03

Xenya


People also ask

What is union type in TypeScript?

TypeScript Union Type TypeScript allows a flexible type called any that can be assigned to a variable whose type is not specific. On the other hand, TypeScript allows you to combine specific types together as a union type. let answer: any; // any type. let typedAnswer: string | number; // union type.

Does not exist on union type?

The "property does not exist on type union" error occurs when we try to access a property that is not present on every object in the union type. To solve the error, use a type guard to ensure the property exists on the object before accessing it.

What is discriminated union TypeScript?

A discriminated type union is where you use code flow analysis to reduce a set of potential objects down to one specific object. This pattern works really well for sets of similar objects with a different string or number constant for example: a list of named events, or versioned sets of objects.

What operator would you use in order to specify a union type in TypeScript?

In TypeScript union types is one of the feature and it is mainly used for to define the user variable which can have multiple set and data types value like integer or number, character, string, float etc these combined data type are referred as union types and it is allowed for the variable with multiple set of data ...


Video Answer


2 Answers

This can be done in typescript 2.8 and later using conditional types. Conditional types iterate over types in a union, union-ing the result:

type Batz = Foo | Bar;

type KeysOfUnion<T> = T extends T ? keyof T: never;
// AvailableKeys will basically be keyof Foo | keyof Bar 
// so it will be  "foo" | "bar"
type AvailableKeys = KeysOfUnion<Batz>; 

The reason a simple keyof Union does not work is because keyof always returns the accessible keys of a type, in the case of a union that will only be the common keys. The conditional type in KeysOfUnion will actually take each member of the union and get its keys so the result will be a union of keyof applied to each member in the union.

like image 88
Titian Cernicova-Dragomir Avatar answered Oct 20 '22 10:10

Titian Cernicova-Dragomir


Instead of a union type, you need an intersection type:

type Batz = Foo & Bar;

I agree that their naming can sometimes be confusing.

like image 31
Behrooz Avatar answered Oct 20 '22 10:10

Behrooz