• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

TypeScript--类型进阶

武飞扬头像
一如彷徨
帮助1

类型推论

  • 类型推论是指能够自动推导值的类型的能力,它是强静态类型语言的特性
  • 如果没有明确的指定类型,那么 TypeScript 会自动推断出一个类型
 let num = 'seven';
 num = 7; // 不能将类型“number”分配给类型“string”

注意:如果定义时没有赋值,不管之后有没有赋值,都会被推断成 any 类型,并完全不被类型检查

 let myVal;
 
 myVal = 7;
 myVal = 'seven'
 myVal = (): void => {}

类型别名

  • 类型别名是给某种类型起别名,常用于对联合类型进行重命名
  • 使用 type 创建类型别名
 type MyString = string // MyString是string类型的别名
 type MyFunc = () => string // MyFunc是返回string类型函数的别名
 type GetString = MyString | MyFunc
 
 function getData(val: GetString): GetString{
   return typeof val === 'string' ? val : val()
 }

字面量类型

  • 在 TypeScript 中,字面量不仅可以表示值,还可以表示类型

包括 3 种字面量类型

  • 字符串字面量类型
  • 数字字面量类型
  • 布尔字面量类型

字符串字面量

  • 字符串字面量类型其实就是字符串常量,它是特定的字符串类型
 type Name = 'Ts'
 
 let name1: Name = 'typeScript' // 不能将类型“"typeScript"”分配给类型“"Ts"”
 let name2: Name = 'Ts'
  • 多个字面量类型组合成一个联合类型,用描述拥有明确成员的集合
 type Week = 'Mon'|'Tue'|"Wed"|'Thu'|'Fri'|'Sat'|'Sun';
 
 function chooseDay(day: Week): void {
   console.log(day);
 }
 
 chooseDay('Mon') // 'Mon'
 chooseDay('today') // 类型“"today"”的参数不能赋给类型“Week”的参数。

数字字面量

数字字面量

  • 数字字面量类型和字符串字面量类型差不多,都是指定类型为具体的值
 type Age = 18;
 
 interface Person {
   name: string,
   age: Age
 }
 
 let p: Person = {
   name: '张三',
   age: 23 // 不能将类型“23”分配给类型“18”
 }

布尔字面量

  • 布尔字面量和上面的两个类似
 type Success = true;
 let res: Success = true;
 let err: Success = false; // 不能将类型“false”分配给类型“true”
  • 由于布尔值只有 truefalse,所以和 boolean 是一样的
 let result1: true | false;
 let result2: boolean;

类型拓宽

  • 字面量类型拓宽就是将字面量类型转换为其父类型

letconst定义的变量的值相同时,变量的类型是怎么样的

  • const 定义: 不定义类型时,推断其类型为字面量类型
 const str = 'Lebron James' // 类型为'Lebron James'
 
 const num = 23 // 类型为23
 
 const flag = true // 类型为true
  • let 定义: 不定义类型时,推断其类型为赋值字面量类型的父类型
 let str = 'Lebron James' // 类型为string
 
 let num = 23 // 类型为number
 
 let flag = true // 类型为boolean

联合类型

  • 联合类型是指将多种类型进行联合,即多个类型的并集,当变量、函数参数的类型不是单一类型,而是多种不同类型的组合时,可以用联合类型

  • 使用 | 分隔每个类型

 let myVal: string | number;
 
 myVal = 7;
 myVal = 'seven'
 myVal = true // 不能将类型“boolean”分配给类型“string | number”

访问属性或方法

  • 当不确定联合类型的变量到底是哪个类型时,只能访问此联合类型的共有属性或方法
 function useWay(val: string | number): void {
   val.toString(); // toString()方法是string和number共有的
 }

学新通

  • 当访问不是 stringnumber 的共有属性时会编译失败
 function useWay(val: string | number): number {
   return val.length; // 类型string | number上不存在属性length
 }
  • 联合类型的变量被赋值时会根据类型推论的规则推断出一个类型
 let myVal: string | number;
 
 myVal = 'Lebron James'
 console.log(myVal.length); // 12
 
 myVal = 1234
 console.log(myVal.length); // 类型“number”上不存在属性“length”

类型缩减

  • 如果联合类型同时包含原始类型和字面量类型,最后会缩减为原始类型,编译器提示变量是原始类型
 type MyNumber = 23 | number // 缩减为number类型
 
 type MyString = 'Kobe' | string // 缩减为string类型
 
 type MyBoolean = false | boolean // 缩减为boolean类型
  • 可以给父类型添加 "& {}" 即可控制类型缩减,编译器会出现提示
 type MyString = 'Kobe' | string & {}

学新通

  • 当接口是联合类型时,并且一个接口的属性是另一个接口属性的子集,该属性也会类型缩减
 type MyInterface = { age: 18 } | { age: 18 | 25 } // age属性发生类型缩减,变成18 | 25

可选与联合

  • 当函数参数是可选类型时,其本质上是 类型|undefined 的联合类型,调用函数时可不传参
 function foo(name?: string) {
  console.log(name)
 }
 
 foo();

学新通

- 如果写成 `string | undefined` 而不是可选形式,则参数是必传的

 function foo(name: string | undefined) {
   console.log(name);
 }
 
 foo(); // 编译不通过

交叉类型

  • 将多个类型合并为一个类型,即多个类型的交集
  • 使用 “&” 操作符来声明交叉类型
 type crossType = string & number; // 同时是string和number类型
  • 像上面代码中,仅仅把原始类型、字面量类型等合并是无意义的,实际上就等于 never
  • 将多个接口类型合并成为一个类型
 type Person = { name: string } & { age: number } & { id: number }
 
 const p: Person = {
   name: '张三',
   age: 18,
   id: 9527
 }
  • 两个接口中同名属性定义了不同类型,合并后为 never 类型
 type Person = { name: string, age: string } & { age: number }
 
 const p: Person = {
   name: '张三',
   age: 18, // 不能将类型“number”分配给类型“never”
 }
  • 两个接口中同名属性,一个为原始类型,一个为字面量类型,合并后为两者中的子类型
 type Person = { name: string, age: number } & { age: 18 };
 
 const p: Person = {
   name: '张三',
   age: 23, // 不能将类型“23”分配给类型“18”
 }
  • 将多个联合类型合并成为一个交叉类型,需要同时满足不同的联合类型限制
 type UnionA = "pink" | 996;
 type UnionB = 996 | 24;
 type UnionC = UnionA & UnionB; // 996
 
 const c: UnionC = 996;
  • 如果多个联合类型中没有相同的类型成员,那么合并出来的类型就是 never 类型
 type UnionA = "pink" | 996;
 type UnionB = false | 24;
 type UnionC = UnionA & UnionB; // never
 
 const c: UnionC = 996 // 不能将类型“number”分配给类型“never”

类型擦除

  • typescript 在编译过程中批注的内容和接口会在运行时利用工具擦除
 interface IPerson {
   name: string
   age: number
 }
 
 const person = {
   name: "Tony",
   age: 18,
   address: '广东省深圳市南山区'
 }
 
 const personInfo: IPerson = person
  • 如上面代码所示,常量 person 会进行类型推断,其中会有 { address: string },当把 person 赋值给personInfo 时,编译器会把多余的属性进行擦除(freshness) ,擦除后若依然满足 IPerson 接口规定的类型,则可以赋值
  • 当擦除后不满足接口规定时,则不会通过编译

学新通

这篇好文章是转载于:编程之路

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 编程之路
  • 本文地址: /boutique/detail/tanhhchaag
系列文章
更多 icon
同类精品
更多 icon
继续加载