🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
>[success] # 类型推导 ~~~ 1.上面的章节已经知道ts 可以类型推导,即不声明类型,ts通过赋值推导当前值类型,这种'类型推断'主要得益于 '在 TypeScript 中,类型标注声明是在变量之后(即类型后置),它不像 Java 语言一样,先声明变量的类型,再声明变量的名称' 1.1.java: String s1 = "Runoob" ,先声明字符串类型在定义变量 1.2.ts: s1:string = "Runoob",先声明变量在定义类型 因此:'使用类型标注后置的好处是编译器可以通过代码所在的上下文推导其对应的类型,无须再声明变量类型' 好处:'使得我们无须显式声明,即可直接通过上下文环境推断出变量的类型,也就是说此时类型可缺省' ~~~ >[danger] ##### 案例一 ~~~ let num = 1 // 帮自动推断出是number 类型 let num1:number = num // 并且将num 赋值个已经声明number类型的num1 也不会报错 ~~~ ![](https://img.kancloud.cn/2a/19/2a192dbcf53c2f92789c0de1cd535ee7_340x75.png) >[danger] ##### 案例二 ~~~ /** 根据参数的类型,推断出返回值的类型也是 number */ function add1(a: number, b: number) { return a + b } const x1 = add1(1, 1) // 根据推断的函数返回类型是number 并且x1也被推导为number ~~~ ![](https://img.kancloud.cn/c3/e3/c3e39d0487c36108a9f422b4d92daa0b_574x146.png) >[danger] ##### 案例三 -- let 和 const ~~~ 1.let 和const 除了最开始说得const 声明的变量必须赋值外,在类型推导上也是有区别的,一下面案例let 可以被自动推导成 number 类型,但是const 只是被推导为是1 2.下面案例发现const在没声明类型时候,推导时候会是具体值,这类类型叫'字面量类型' 3.当const 变量'具象化',例如下面案例 const a:1 = 1 a已经具象化了字面量此时赋值给 let 声明,let也会被具象化, 如果没有被具象化的话,let 赋值就会变成其对应父级 ~~~ * 案例 ~~~ const num1 = 1 let num = 1 num = num1 // 数字类型可以互相赋值 ~~~ ![](https://img.kancloud.cn/ea/b1/eab16e919e3410c7e6a3e3cc49c6751f_326x123.png) ![](https://img.kancloud.cn/15/02/150292d7b52b59c820e313bdcefdfe5f_289x100.png) * 案例 ~~~ const num1 = 1 let num = num1 // num 被推导为是数字类型number num = 2 // 正常不报错 const str1 = "1111" ~~~ ![](https://img.kancloud.cn/37/57/37575c24e21b10422e304ab0956bafc9_287x147.png) ![](https://img.kancloud.cn/12/74/1274c154cad9cfa06544938796c55875_302x78.png) * 案例 具体字面量类型 ~~~ const specifiedStr: 'this is string' = 'this is string'; // 类型是 '"this is string"' let str2 = specifiedStr; // 即便使用 let 定义,类型是 'this is string' str2 = "111" // 报错 const num1:1 = 1 let num = num1 num = 2 // 报错 ~~~ ![](https://img.kancloud.cn/2f/fe/2ffe30a7fa221800c8f877ac38a75e25_642x130.png) >[success] # 字面量类型 ~~~ 1.通过上面const 和let 案例发现const 在没有声明变量时候,const 定义为一个不可变更的常量,在缺省类型注解的情况下, TypeScript 推断出它的类型直接由赋值字面量的类型决定,这类就属于'字面量类型' 相对let 来说,缺省显式类型注解的可变更的变量的类型转换为了赋值字面量类型的父类型 2.TypeScript 支持 3 种字面量类型:字符串字面量类型、数字字面量类型、布尔字面量类型 3.字符串类型不一定都能赋值给字符串字面量类型,字符串是一个大集合,字符串字面量类型是集合中一小部分,只能小集合 赋值给大集合而不能大集合值赋值给小集合,是一个包含关系,数字字面量类型、布尔字面量类型都是同理 ~~~ ~~~ { let specifiedStr: 'this is string' = 'this is string'; let str: string = 'any string'; specifiedStr = str; // ts(2322) 类型 '"string"' 不能赋值给类型 'this is string' str = specifiedStr; // ok } ~~~ ![](https://img.kancloud.cn/f9/03/f9030f099045cdabfd1bd39801249342_679x262.png) >[danger] ##### 场景 ~~~ 1.除了const 在没有声明类型时候会被'类型推断'为字面量,还有'联合类型'时候也会用字面量 type Direction = 'up' | 'down'; function move(dir: Direction) { // ... } move('up'); // ok move('right'); // ts(2345) Argument of type '"right"' is not assignable to parameter of type 'Direction' ~~~ >[danger] ##### 总结 ~~~ 1. TypeScript 的字面量子类型会转换,相对来说const 在不声明类型情况下会是直接使用对应赋值的字面量类型,let 在没有 声明变量的情况下会对赋值变量进行向上转型为其对应的父类型这种设计称之为 "literal widening" 2.let 声明的简单类型字面量会拓宽类型,const 声明的简单类型字面量会收窄,const 声明的对象变量会自动推断对应的类型, 可以用as const(可以参看断言章节) 收窄,让每一个key都是固定类型 ~~~