Cross-type
The plurality of types of combined into a type, and to two types of sets. The difference between inherited, inheritance can have their own attributes, but there is no cross.
{DogInterface interface RUN (): void } interface CatInterface { Jump (): void } the let PET: DogInterface & CatInterface = {// looks like multiple inheritance and interfaces, with one exception. Inheritance can have their own attributes, not cross. RUN () {}, Jump () {}, };
Union type
Type declaration is uncertain, it may be more than one type.
let a: number | string = " a"; // type defined let b: "a" | " b" | "c"; // Value defined let c: 1 | 2 | 3 | "v"; // limited value
Protection type can be distinguished:
There are two // shape, area function is used to calculate the area of each shape. interface Square { kind: "Square"; size: Number; } interface the Rectangle { kind: "Rectangle", width: Number, height: Number, } type the Shape = Square | the Rectangle; function Area (S: the Shape) { Switch (S .kind) { Case "Square": return s.size * s.size; // within this block, to ensure that only the size attribute Case "Rectangle": return s.height * s.width; } } the console.log (Area ({kind: "Square", size: 10})); // 100 // now add a shape: circular. To define the interface Circle, was added to the joint type Circle Shape, and a case of increasing the area function. But if we forget to modify the area function, what happens? interface Circle { kind: "circle", r: Number The, } of the type the Shape = Square | of the Rectangle | Circle; console.log (Area ({kind: "Circle", r: 10})); // undefined, an error is not here, does not meet our expectations. We hope that in time it can be exposed bug, increase the stability of the program. Make the following changes: function Area (S: the Shape) { Switch (s.kind) { Case "Square": return s.size * s.size; Case "Rectangle": return s.height * s.width; Case "Circle ": return Math.PI SR *; default: return ((E: the any) => {the throw new new Error (` $ {s} is not defined area calculation `)}) (s) // this step is important, be sure to throw an exception here } }
Index Type
When we use the index does not exist, it will return undefined, there is no constraint (the following code). So we need to have constraints on the index.
{obj = the let A:. 1, B: 2, C:. 3, }; function the getValue (obj: the any, Keys: String []) { return keys.map (Key => obj [Key]); } the console.log (the getValue (obj, [ "a", "B"])); the console.log (the getValue (obj, [ "C", "F"])); // find, 'f' corresponding to the output is undefined no constraints, need to use index type
Use the following index types:
function getValue <T, K extends keyof T> (obj: T, keys: K []): T [K] [] {// T [k] [] represents the return value must be a list of values consisting of obj return keys.map (key => obj [ key]); // this case the elements only in keys in the key obj } the console.log (the getValue (obj, [ "a", "B"])); console.log (getValue (obj, [ " c", "f"])); // this case will be given, with the constraint 'f' is not in "a " | "b" | "c"
Let's explain:
Here the use of two operators, and query operators access operator keyof T T [k] (see example below). <T, K extends keyof T> uses generic constraints, the value of the parameter K is constrained only parameter data in the bound T "key."
// keyof T interface Obj{ a: number; b: string; } let key: keyof Obj; // 此时key表示 'a' | 'b' // T[k] let value: Obj['a'] // number
Mapping Types
You can generate a new type from the old type. For example, all members of the interface becomes read-only, optional.
TS built a lot of mapping types.
{Obj interface A: String; B: Number; C: Boolean; } // Obj the interface member into each read-only property, generates a new interface. type ReadonlyObj = Readonly <Obj>; // Readonly TS is built mapping types, the same below // Readonly realization principle, the use of the index type method of operating type Readonly <T> = { Readonly [T P in keyof]: T [ P]; }
Another example:
// optional attribute becomes all type PartialObj the Partial = <the Obj>; // implementation principle of the Partial type the Partial <T> = { [P T in keyof] ?: T [P]; } // Get original subtype set type of Pick PickObj = <the Obj, 'a' | 'B'>; // equivalent interface PickObj { a: String, B: Number } // type as original members of the new type of type RecordObj = Record < 'x' | 'Y', the Obj>; // equivalent interface RecordObj { X: the Obj, Y: the Obj, }
sofa
Condition Type
Condition type refers to the type of expression of the decision. The type of condition type does not have the uniqueness, increasing the flexibility of the language.
E.g:
T extends U X:? Y said that if the type T can be assigned to type U, name given to the results of X type, Y type or else giving
Another example:
the TypeName type <T> = T the extends String String:? T the extends Number Number:? T the extends Boolean Boolean:? T the extends undefined undefined:? T the extends Function Function:? Object; type = Tl the TypeName <String>; // to Tl type string type T2 = TypeName <string [] >; // T2 type object type T3 = TypeName <function>; // T3 is a function type type T4 = TypeName <string | string []>; // T4 to a string and joint type of object
What can be used to do?
(A | B) extends U ? X : Y 解析为(A extends U ? X : Y) | (B extends U ? X : Y)
This can be used to make the type of filter, for example:
Diff type <T, the U-> T = the extends the U-Never: T;? type = T5 Diff < 'A' | 'B' | 'C', 'A' | 'E'>; // first role is to filter out the parameter 'a'. T5 is a 'b' | 'c' joint type resolution process: Diff < 'A', 'A' | 'E'> | Diff < 'B', 'A' | 'E'> | Diff < 'C', 'A' | 'E'> Never | 'B' | 'C' 'B' | 'C'
TS built-in condition type:
Exclude <T, U> // assignment can be excluded from T to type U, corresponds to the above example Diff the Extract <T, U> // T may be assigned to the extracted type U. NonNullable <T> // T excluded from null and undefined. ReturnType <T> // Get the type of function return value. InstanceType <T> // Get an instance of the type constructor type.