交叉类型
- 将多个类型合并成为一个新的类型,新类型具有所有类型的特性
interface A{
name:string
}
interface B{
age:number
}
type C=A & B
const c:C={
name:'jack',
age:19
}
console.log(c)
联合类型
- 表示必须满足其中一个
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))
类型保护
- 类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型
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类型保护,类型只能是string/number/boolean/symbol中的一种
- instanceof类型保护
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)
}
类型别名
- 可以对类型名字重新定义
- 类型别名可以嵌套
- 为接口起别名时,不能使用extends | 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'))
可辨识联合
- 具有普通的单例类型属性— 可辨识的特征
- 一个类型别名包含了那些类型的联合
- 此属性上的类型保护
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))
多态的this类型
- 也就是接口或者类的子类型
- 在父类型中方法结束时return当前实例对象出去,让子类不具备此方法但依然可以调用父类的方法
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)
索引类型
- keyof 索引类型查询操作符
- T[K] 索引访问操作符,也就是T上是否有K
- 可以检查对象上是否有对应键值对
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)
映射类型
- 从旧类型中创建出一个新的类型
- TS内置Readonly只读和Partial可选
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
- 任何类型都可以赋值给unknown类型
- 如果没有类型断言或者基于控制流的类型细化时,unknown不可赋值给其他类型
- 如果没有类型断言或者基于控制流的类型细化时,不能在上面进行任何操作
- unknown与任何其他类型组成的交叉类型,返回其他类型
- unknown与其他类型(除了any是any)组成的联合类型,都等于unknown
- never是unknown的子类型
- keyof unknown是never类型
- 只能对unknown进行等或不等操作,不能进行其他操作
- unknown类型的值不能访问它的属性,不能作为函数调用,不能作为类创建实例
- 如果映射用的unknown类型,则不会映射任何类型
条件类型
- 类似于三元运算符
- 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 Type1<T>=T extends Array<infer U> ? U : T;
type type=Type1<string[]>
type Type1=Exclude<'a'|'b'|'c', 'a'>
type Type2=Extract<'a'|'b'|'c', 'a'>
- NonNullable 去除null和undefined | ReturnType 返回函数的返回类型
type Type1=NonNullable<string | number | null | undefined>
type Type2=ReturnType<()=>string>
class AClass{
constructor(public name:number=10) {
}
}
type Type1=InstanceType<typeof AClass>
type Type2=InstanceType<any>