TS — 类型推论和兼容
最后更新于:2022-04-02 08:11:24
[TOC]
>[success] # 类型类型推论和兼容
~~~
1.'类型推论':TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型
2.'类型兼容':'TypeScript'的类型系统允许某些在编译阶段无法确认其安全性的操作。当一个类型系统具此属性时,
被当做是“不可靠”的。我的理解就是'你我本无缘都靠长得像'
~~~
>[info] ## 类型推论
~~~
1.TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型
~~~
>[danger] ##### 通用类型
~~~
1.ts 会根据赋值做出类型推论
~~~
~~~
let name1 = 'wang' // 等同于 let name1:string = 'wang'
let arr = [1,'a'] // let arr: (number|string)[] = [1,'a']
arr = [1, 'a', 1]
// arr = [1, 'a', true] // 报错
// 如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:
let myFavoriteNumber;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
~~~
>[danger] ##### 上下文归类
* 这里有个小疑问后期调查一下
~~~
// 正常情况下如果没有给a赋值类型,a会被自动推断类型为MouseEvent
// 但是现在没有 需看时候后期需要配置什么
window.onmousedown = (a)=> {
console.log(11)
}
~~~
* 如果我们不知道我们参数的类型是什么,又不想使用any,可以如图查看
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/65/47/6547911c1a638af35ef4a9b832706cd6_875x258.png)
~~~
window.onmousedown = (a:MouseEvent)=> {
console.log(11)
}
~~~
>[info] ## 类型兼容
~~~
1.'TypeScript'的类型系统允许某些在编译阶段无法确认其安全性的操作。当一个类型系统具此属性时,
被当做是“不可靠”的。我的理解就是'你我本无缘都靠长得像'
~~~
>[danger] ##### 基本规则
~~~
1.下面有个案例'infos'的类型已经定义好是一个包含'name'字段,我们以把只具有一个'name'字段的属性'infos1'
赋值给infos是可以的,在吧infos2 这种只要包含'name'字段的对象赋值也是可以的。但是'infos3'这种不具备包含
'name'字段的对象赋值就发现报错
3.'总结':'类型兼容性 如果x要兼容y,那么y至少具有与x相同的属性',你可以把'多的赋值给少的',但是不能'把少'的赋值
给'多的'
~~~
~~~
interface Info{
name:string
}
let infos:Info
const infos1 = { name: 'w' }
const infos2 = {name:'w',age:12}
const infos3 = { age: 18 }
infos = infos1
infos = infos2
// infos2 = infos // 报错 少的赋值给多的
// infos = infos3 // 报错的
~~~
* 注意我们上面案例是 两种变量相互赋值
~~~
1.不是下面这种定义了规定类型,赋值后却不按照规定类型赋值
2.'注意':上面是两个变量相互赋值,下面这个是对定义变量赋值不要搞错
~~~
~~~
interface Info{
name:string
}
// let infos:info = {name:'w',age:12} // 报错的
// let infos:info
// infos = {name:'w',age:12} // 报错
~~~
>[danger] ##### 函数兼容 -- 函数参数
~~~
1.参数个数一致,类型不同,是不能相互赋值的
2.参数个数不一致,相同类型参数的位置也不一致,是不可以相互赋值的
3.参数个数不一致,相同类型参数的位置一致,可以相互赋值,但是'只能把少的赋值给多的'
~~~
* 首先参数个数一致,类型不同
~~~
let xx = (a: number) => 0
let yy = (a: string) => 0
// xx = yy // 报错参数类型不一致
~~~
* 参数个数不一致,相同类型参数的位置也不一致
~~~
let x = (c: number) => 0
let y = (a: string, b: number) => 0
// xx = yy // 报错
~~~
* 参数个数不一致,相同类型参数的位置一致,可以相互赋值,但是'只能把少的赋值给多的
~~~
1.解释为什么只能把少的赋值给多的,你把少的赋值给多,多的那个没被赋值的参数相当于'undefind' 没有影响,
但是你把多的赋值给少的,少的无缘无故多了一个参数那就报错了
~~~
~~~
let x = (a: number) => 0
let y = (a: number,b:string) => 0
y=x // 把少的 给多的,多的可以只用一个参数另一不用
// x = y // 把多的参数,赋值给少参数,因为x定义只有一个a,你多给他一个b他也用不了
~~~
>[danger] ##### 函数兼容 -- 剩余参数
~~~
1.当一个函数有剩余参数时,它被当做无限个可选参数
~~~
~~~
const getSum = (nlist:number[],callback:(...args:number[])=>number)=>{
callback(...nlist)
}
getSum([1,2,3],(...args:number[])=>{
const sum = args.reduce((a, b) => a + b)
console.log(sum) // 6
return sum
})
getSum([1, 2, 3], (n1:number,n2:number) => {
console.log(n1+n2)
return n1+n2
})
~~~
>[danger] ##### 函数兼容 -- 函数参数双向协变
~~~
1.当A的参数类型不确定,B 的参数类型为A中不确定参数类型中的一个。可以吧多类型赋值给少类型的
~~~
~~~
let funcA = (arg1: number | string) => { }
let funcB = (arg1: number ) => { }
// funcA = funcB // 错误的
funcB = funcA
~~~
>[danger] ##### 函数兼容 -- 返回值类型
~~~
1.函数返回类型可以把少的赋值给多的,多的不能赋值给少的
~~~
~~~
let funcTypeA = (): string | number => 0
let funcTypeB = (): number => 0
funcTypeA = funcTypeB
// funcTypeB = funcTypeA // 报错
~~~
>[danger] ##### 函数兼容 -- 函数的重载
~~~
1.重载类型不一致怎么赋值都是错
~~~
~~~
function merge(n1: number, n2: number): number
function merge(n1: string, n2: string): string
// 虽然是any 但是只能是 string 或者 number
function merge(n1:any,n2:any):any{
return n1+n2
}
function sum(n1: number, n2: number): number
function sum(n1: any, n2: any): any {
return n1 + n2
}
// 问题重载类型不一致怎么赋值都是错
// merge = sum // 报错
// sum = merge // 报错
~~~
>[danger] ##### 枚举的兼容
~~~
1.不同枚举类型是不兼容的
~~~
~~~
enum StatusEnum{
Off,
On
}
enum AnimalEnum{
Dog,
Cat
}
let s = StatusEnum.Off
// s = AnimalEnum.Dog // 不同枚举类型是不兼容的
~~~
>[danger] ##### 类
~~~
1.类有静态部分和实例部分的类型。 比较两个类类型的对象时,只有实例的成员会被比较。
静态成员和构造函数不在比较的范围内
2.向下面的案例'AnimalClass ' 和'PeopleClass',中 因为static 是静态类方法所以他们age属性是不影响他们相互赋值
,比较的都是实例成员,也因此'FoodIsClass ' 的name属性类型和另外两个不一致不能相互赋值
~~~
~~~
class AnimalClass {
public static age: number
constructor(public name: string) {}
}
class PeopleClass {
public static age: string
constructor(public name: string) {}
}
class FoodIsClass {
constructor(public name: number) {}
}
let animal: AnimalClass = new AnimalClass('w')
let people: PeopleClass = new PeopleClass('w')
let food: FoodIsClass = new FoodIsClass(1)
people = animal
// animal = food // 报错
~~~
* 类的私有成员和受保护成员? 后续看
>[danger] ##### 泛型
~~~
1.如果定义接口里面没东西,那么泛型类型可以交叉赋值,如果有了东西类型不一致就报错了
~~~
~~~
interface Empty {
}
let x: Empty;
let y: Empty;
x = y;
interface NotEmpty {
data: T;
}
let x: NotEmpty;
let y: NotEmpty;
x = y; // Error, because x and y are not compatible
~~~
';