cross type
Merge multiple types into a new type that has all the properties of the type
interface A {
name: string
}
interface B {
age: number
}
type C = A & B
const c: C = {
name: 'jack' ,
age: 19
}
console . log ( c)
union type
Indicates that one of the
const getLengthFunc= ( content: string | number ) : number => {
if ( typeof content=== 'string' ) return content. length
else return content. toString ( ) . length
}
console . log ( getLengthFunc ( '123' ) )
console . log ( getLengthFunc ( 123 ) )
type protection
Type guards are expressions that are checked at runtime to ensure that the type
const getRandomValue = ( ) => {
const num= Math. random ( )
if ( num> 0.5 ) return '123'
else return 123
}
const item= getRandomValue ( ) ;
function isString ( value: string | number ) : value is string {
return typeof value === 'string'
}
if ( isString ( item) ) {
console . log ( item. length)
} else {
console . log ( item. toFixed ( ) )
}
typeof type protection, the type can only be one of string/number/boolean/symbol
instanceof type protection
class CreatClass1 {
public name= 'jack'
}
class CreatClass2 {
public age= 20
}
function getRandomClass ( ) {
const random= Math. random ( )
return random> 0.5 ? new CreatClass1 ( ) : new CreatClass2 ( )
}
const item= getRandomClass ( )
if ( item instanceof CreatClass1 ) {
console . log ( item. name)
} else {
console . log ( item. age)
}
type alias
Type names can be redefined
Type aliases can be nested
You cannot use extends | interface when aliasing an interface
type TypeString = string
let str: TypeString;
type PositionType< T > = {
x: T ,
y: T ,
}
const position: PositionType< number >= {
x: 1 ,
y: 1
}
console . log ( position)
type Childs< T > = {
current: T ,
child? : Childs< T >
}
const c: Childs< string >= {
current: 'first' ,
child: {
current: 'second' ,
child: {
current: 'third'
}
}
}
console . log ( c)
type Direction = 'first' | 'second' | 'third' ;
function getDirction ( direction: Direction) {
return direction. substr ( 0 , 1 )
}
console . log ( getDirction ( 'first' ) )
Discriminated Union
Has common singleton type properties—discernible traits
A type alias contains unions of those types
type guard on this property
interface Square {
kind: 'Square' ,
size: number
}
interface Rectangle {
kind: 'Rectangle' ,
height: number ,
width: number
}
interface Circle {
kind: 'Circle' ,
radius: number
}
type Shape = Square | Rectangle | Circle;
function assertNever ( value: never ) : never {
throw Error ( 'Unexpected object' + value) } function getArea ( c: Shape) : number {
switch ( c. kind) {
case 'Square' : return c. size; break ;
case 'Rectangle' : return c. width* c. height; break ;
case 'Circle' : return Math. PI * c. radius** 2 ; break ;
default : return assertNever ( c)
} } const circle: Circle= {
kind: 'Circle' ,
radius: 20 } console . log ( getArea ( circle) )
polymorphic this type
That is, a subtype of an interface or a class
Return the current instance object when the method ends in the parent type, so that the subclass does not have this method but can still call the method of the parent class
class Counter {
constructor ( public count: number = 0 ) {
}
public add ( value: number ) {
this . count+= value;
return this ;
}
public subtract ( value: number ) {
this . count-= value;
return this ;
}
}
const counter= new Counter ( 10 )
counter. add ( 1 ) . subtract ( 2 )
console . log ( counter)
class PowCounter extends Counter {
constructor ( count: number ) {
super ( count) ;
}
public pow ( value: number ) {
this . count= this . count** value;
}
}
const powCounter= new PowCounter ( 20 )
powCounter. pow ( 2 )
powCounter. add ( 100 )
console . log ( powCounter)
index type
keyof index type query operator
T[K] index access operator, that is, whether there is K on T
Can check whether there is a corresponding key-value pair on the object
interface InfoI {
name: string ,
age: number
}
let infoProps: keyof InfoI
infoProps= 'name'
infoProps= 'age'
function getValue < T , K extends keyof T > ( obj: T , names: K [ ] ) : T [ K ] [ ] {
return names. map ( item=> obj[ item] )
}
const infoObj= {
name: 'jack' ,
age: 20
}
const infoValue: ( string | number ) [ ] = getValue ( infoObj, [ 'name' , 'age' ] )
console . log ( infoValue)
mapping type
create a new type from an old type
TS built-in Readonly read-only and Partial optional
type MapToPromise< T > = {
[ K in keyof T ] : Promise < T [ K ] >
}
type Tuple = [ number , string , boolean ]
type promiseTuple = MapToPromise< Tuple>
let tuple: promiseTuple= [
new Promise ( ( resolve) => resolve ( 1 ) ) ,
new Promise ( ( resolve) => resolve ( '1' ) ) ,
new Promise ( ( resolve) => resolve ( false ) ) ,
]
console . log ( tuple)
unknown
Any type can be assigned to the unknown type
If there is no type assertion or type refinement based on control flow, unknown cannot be assigned to other types
Nothing can be done on it without type assertion or type refinement based on control flow
The intersection type of unknown and any other type, returns the other type
The joint type composed of unknown and other types (except any is any) is equal to unknown
never is a subtype of unknown
keyof unknown is never type
You can only perform wait or wait operations on unknown, and no other operations can be performed
A value of unknown type cannot access its properties, cannot be called as a function, and cannot be used as a class to create an instance
If the unknown type is used for mapping, no type will be mapped
condition type
Similar to the ternary operator
T extends U ? X : Y
type Type< T > = T extends string ? string : number
let type: Type< string >= 'a'
type Type2< T > =
T extends string ? string :
T extends number ? number :
T extends ( ) => void ? ( ) => void :
object;
type type2 = Type2< ( ( ( ) => void ) | number ) >
Type inference infer for conditional types
type Type1< T > = T extends Array < infer U > ? U : T ;
type type = Type1< string [ ] >
Exclude intersection | Extract union
type Type1 = Exclude< 'a' | 'b' | 'c' , 'a' >
type Type2 = Extract< 'a' | 'b' | 'c' , 'a' >
NonNullable removes null and undefined | ReturnType returns the return type of the function
type Type1 = NonNullable< string | number | null | undefined >
type Type2 = ReturnType< ( ) => string >
InstanceType infers the type of the class from the type
class AClass {
constructor ( public name: number = 10 ) {
}
}
type Type1 = InstanceType< typeof AClass>
type Type2 = InstanceType< any >