builtin generic types available in TypeScript (utility types)¶
Array <T/>
Promise <T>
Partial <T> (partially applied type, make all properties optional)
Omit <T, K> (omit properties, K is a list of properties to omit, returns a new type minus the properties in K)
Readonly <T> (readonly properties, returns a new type with readonly properties)
Required <T> (make all properties required, returns a new type with required properties)
Record <Keys, Type>
Pick <T, K> (returns a new type with only the properties in K)
Exclude <UnionType, ExcludedMembers> (expects 2 union types, returns a new union type with all members of UnionType except for the members in ExcludedMembers)
Extract<Type, Union> returns the a type that’s the intersection of Type and Union
NonNullable <Type> returns a new type excluding null and undefined
Parameters <Type> expects a function type and return a tuple type of its parameters
ReturnType <Type> expects a function type and returns the return type of the function.
ConstructorParameters <Type> expects a constructor function type and returns a tuple type of its parameters
InstanceType <Type> expects a class type and returns a type of the instance that this class will produce.
ThisParameterType <Type> extracts the type of this in a function type.
OmitThisParameter <Type> removes this parameter from a function type.
functionmerge<T,U>(obj1:T,obj2:U):T&U{returnObject.assign(obj1,obj2);// or as T & U}constmerged=merge({name:"Max"},{age:30});merged.name;// "Max"merged.age;// 30merged.isAdmin;// error, isAdmin is not defined on type T & U as {name: string} & {age: number}
you can specify constraints on a generic type, so that it can only be used with specific types.
you specify constraints on generic types by using the extends keyword.
// no constraint, problemfunctionmerge<T,U>(obj1:T,obj2:U):T&U{returnObject.assign(obj1,obj2);// or as T & U}constmerged=merge({name:"Max"},30);// {name: max},// Object.assign fails silently if not in strict mode since the second parameter is not an objectmerged.age.toString();// error, can not access toString() of undefined// constraint, solutionfunctionmerge<Textendsobject,Uextendsobject>(obj1:T,obj2:U):T&U{returnObject.assign(obj1,obj2);// or as T & U}constmerged=merge({name:"Max"},30);// error, 30 is not an object
add constraint so that the passed generic type is guaranteed to have a specific property.
typeWithLength={length:number};functiondescribeLen<TextendsWithLength>(x:T):[T,string]{if(x.length>1){// without this constraint, it will be an error, since length is not on type Treturn[x,`x has ${x.length} elements`];}return[x,`x has no elements`];}describeLEn("abc");// "x has 3 elements", string has a length propertydescribeLen(["a","b","c"]);// "x has 3 elements", array has a length propertydescribeLen({length:10});// "x has 10 elements", object has a length propertydescribeLen({});// error, object has no length propertydescribeLen(1);// error, number has no length property
add constraint so that the passed generic type is guaranteed to have a specific property that belongs to a specific type.
functionextractAndConvert<Textendsobject,UextendskeyofT>(obj:T,key:U):T[U]{// using keyof, you can only access the properties of the object that are defined in the type T// we can also know the return type of the property obj[key]returnobj[key];}
if the data in the class is generic, you can specify the type of the data in the class.
classGenericStorage<Textendsnumber|string|boolean>{data:T[]=[];add:(x:T)=>{this.data.push(x);returnthis.data;};}conststorage=newGenericStorage<number>();storage.add(1);//worksstorage.add("a");//error, "a" is not a numberconsts2=newGenericStorage<object>();//error, object is not allowed (T extends number | string | boolean)
convert an array of strings to literal union type¶
constarr=["a","b","c"];asconst;// as const, makes array as ReadonlyArray<"a"|"b"|"c">typeArrKeys=typeofarr[number];// "a" | "b" | "c"
constobj={a:1,b:2,c:3,d:4,e:5,f:6,};constkeysToPick=["a","b","c"]asconst;// as const, makes array as ReadonlyArray<"a"|"b"|"c">typePickedKeys=typeofkeysToPick[number];// convert string[] to literal string union type, so it can be used in Pickconstpicked:Pick<typeofobj,PickedKeys>={a:1,b:2,c:3};constkeysToOmit=["a","b","c","d","e"]asconst;// as const, makes array as ReadonlyArray<"a"|"b"|"c"|"d"|"e"">typeOmittedKeys=typeofkeysToOmit[number];// convert string[] to literal string union type, so it can be used in Omitconstomitted:Omit<typeofobj,OmittedKeys>={f:6};
Exclude expects 2 union types, and returns a union type of the excluded members.
constarr=["a","b","c"]asconst;// as const, makes array as ReadonlyArray<"a"|"b"|"c">typeArrKeys=typeofarr[number];// "a" | "b" | "c"typeExecutedKeys=Exclude<ArrKeys,"b">;// "a" | "c"typeTodo={title:string;description:string;completed:boolean;};constkeys=["title","completed"]asconst;typekeysT=typeofkeys[number];typeExcluded=Exclude<keyofTodo,keysT>;// "description"
Extract\ returns the a type that’s the intersection of Type and Union
Parameters<T> returns the type of the parameters of the function T
declarefunctionf1(arg:{a:number;b:string}):void;typeParametersOfF1=Parameters<typeoff1>;// type T3 = [arg: { a: number; b: string;}]typeT0=ParametersOfF1[0];// { a: number; b: string; }typeT1=Parameters<string>;// error, string is not a function
ReturnType<T> returns the type of the return value of the function T
ReturnType \ expects a function type and returns the return type of the function.
declarefunctionf1(arg:{a:number;b:string}):void;typeT0=ReturnType<typeoff1>;// voidtypeT8=ReturnType<Function>;// error, Function is not a `function type` as (arg: any) => any