Since there aren’t many advanced types officially available, let’s explain them all to make our development more efficient. Partial, Readonly, Record, and Pick are the most frequently used ones in Typescript, so they are not repeated here.
Note: Advanced type declarations, including conditional types, mapping types, type inferences, and never types, have been shared before, as you can see in my column. (In fact, the previous reading is a prerequisite for introducing the official high-level type)
These are advanced types that you probably won’t use, but a quick look at what TS presets will do, and when certain open scenarios come to mind, it’s always a pleasant surprise. (These features are written based on v3.8-beta.)
Required< T >
/** * Make all properties in T required */
type Required<T> = {
[P inkeyof T]-? : T[P]; };Copy the code
Contrary to what Partial
program types do, make all type attributes mandatory.
type Coord = Required<{ x: number, y? :number} >./ / is equivalent to
type Coord = {
x: number;
y: number;
}
Copy the code
Mainly because -? The ability to map conditional decorators, removing all optional parameter states. More decorators address TypeScript Mapped types (e.g. {[P in K]: T[P]}) that can be shared previously.
Exclude<T, U>
/** * Exclude from T those types that are assignable to U */
type Exclude<T, U> = T extends U ? never : T;
Copy the code
Exclude a subtype specified in a union type:
type T0 = Exclude<'a' | 'b' | 'c'.'b'> // 'a' | 'c'
type T1 = Exclude<string | number | boolean.boolean> // string | number
Copy the code
This is primarily a parse-deferred feature based on the extends condition type, which returns all candidate types other than a match, combined with the null value feature of the never type to implement this advanced type.
Extract<T, U>
/** * Extract from T those types that are assignable to U */
type Extract<T, U> = T extends U ? T : never;
Copy the code
The complete opposite of Exclude
, used to extract the specified union type or return never if no extract type exists. Can be used to determine whether a complex union type contains a specified subtype:
type T0 = Extract<'a' | 'b' | 'c'.'a'> // 'a'
type T1 = Extract<string | number | boolean.boolean> // boolean
Copy the code
Omit<T, K extends keyof any>
/** * Construct a type with the properties of T except for those in type K. */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Copy the code
Exclude attributes specified in the interface:
interface I1 {
a: number;
b: string;
c: boolean;
}
type AC = Omit<I1, 'b'>; // { a:number; c:boolean }
type C = Omit<I1, 'a' |'b'> // { c: boolean }
Copy the code
This is also used more frequently in advanced types.
NonNullable< T >
/** * Exclude null and undefined from T */
type NonNullable<T> = T extends null | undefined ? never : T;
Copy the code
Filter null and undefined from union types:
type T1 = NonNullable<string | null | undefined>; // string
Copy the code
As an additional note, null and undefined can be assigned to any type due to their special nature, which can cause unexpected errors. When you enable –strictNullChecks, TS checks strictly and can only be assigned if it is declared null:
/ / close - strictNullChecks
let s: string = "foo";
s = null; / / normal
/ / open - strictNullChecks
s = null; // Error: Type 'null' is not assignable to type 'string'.
Copy the code
Parameters<T extends (… args: any) => any>
/** * Obtain the parameters of a function type in a tuple */
type Parameters<T extends(... args:any) = >any> = T extends(... args: infer P) =>any ? P : never;
Copy the code
Gets all the argument types of the function, as tuples:
type F1 = (a: string, b: number) = > void;
type F1ParamTypes = Parameters(F1); // [string, number]
Copy the code
If you want to see how this works, look at the Infer type inference capability of TypeScript conditional types we shared earlier.
ConstructorParameters<T extends new (… args: any) => any>
/** * Obtain the parameters of a constructor function type in a tuple */
type ConstructorParameters<T extends new(... args:any) = >any> = T extends new(... args: infer P) =>any ? P : never;
Copy the code
The type is similar, except that all the arguments to the constructor are taken. About constructor declarations and how to use this advanced type:
interfaceIEntity { count? :(a)= > number
}
interface IEntityConstructor {
new (a: boolean, b: string): IEntity;
}
class Entity implements IEntity {
constructor(a: boolean, b: string) {}}type EntityConstructorParamType = ConstructorParameters<IEntityConstructor>; // [boolean, string]
Copy the code
What does the IEntityConstructor interface do here? It comes in handy when based on creating instance functions:
function createEntity(ctor: IEntityConstructor, ... arg: EntityConstructorParamType) :IEntity {
return newctor(... arg); }const entity = createEntity(Entity, true.'a');
Copy the code
ReturnType<T extends (… args: any) => any>
/** * Obtain the return type of a function type */
type ReturnType<T extends(... args:any) = >any> = T extends(... args:any) => infer R ? R : any;
Copy the code
Receives a function declaration and returns the return value type of the function, or a combined type if there are multiple types:
type F1 = (a)= > Date;
type F1ReturnType = ReturnType<F1>; // Date
Copy the code
InstanceType<T extends new (… args: any) => any>
/** * Obtain the return type of a constructor function type */
type InstanceType<T extends new(... args:any) = >any> = T extends new(... args:any) => infer R ? R : any;
Copy the code
Gets the return type of the constructor, or if there are more than one, returns it as a union type, using the above definition:
type EntityType = InstanceType<IEntityConstructor>; // IEntity
Copy the code
ThisParameterType< T >
/** * Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter. */
type ThisParameterType<T> = T extends (this: infer U, ... args:any[]) = >any ? U : unknown;
Copy the code
Returns the data type of this in the function, or unknown if none exists:
interface Foo {
x: number
};
function fn(this: Foo) {}
type Test = ThisParameterType<typeof fn>; // Foo
Copy the code
Since we can declare this of a function in TS, this method is used to get this declaration, specifically using:
fn.bind({ x: 1 }); / / normal
fn.bind({ x: '1' }); // Error: ... Type 'string' is not assignable to type 'number'...
Copy the code
OmitThisParameter< T >
/** * Removes the 'this' parameter from a function type. */
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends(... args: infer A) => infer R ?(. args: A) = > R : T;
Copy the code
Remove this data type from function:
interface Foo {
x: number
};
type Fn = (this: Foo) = > void
type NonReturnFn = OmitThisParameter<Fn>; // () => void
Copy the code
Function types declaring this class have the following effects:
function f(this: void) {} // This declaration cannot be used within functions
Copy the code