typescript-类型别名

类型别名

类型别名用来给一个一个类型起一个新名字

简单例子

type Name = string
type NameResolver = () => string
type NameOrResolver = Name | NameResolver
function getName(n: NameOrResolver):Name {
  if (typeof  n === 'string') {
    return  n
  }
  return  n()
}

上例中,我们使用type创建类型别名

类型别名常用语联合类型

interface和type的区别

不同点
语法上

typeinterface的语法不一样,type需要等号,interface不需要

interface User {
    name: string
    age: number
    sayHello: () => void
    sayHi():void
  }
  type UserType = {
    name: string
    age: number
    sayHello: () => void
    sayHi():void
  }
定义的类型上
  • 接口主要声明的是函数和对象,并且总是需要引入特定的类型
  • 类型别名声明的可以是任何的数据类型(基本类型别名,联合类型,元组等类型)
// 接口定义类型检查
  interface Point {
    x: number
    y: number
  }
  // 接口定义函数
  interface SetPoint {
    (x:number, y: number) : void
  }
  // 类型别名定义类型检查
  type PointType = {
    x: number
    y : number
  }
  // 定义函数
  type setPointType = (x:number, y : number) => void
  // 定义原生类型
  type Name = string
  // 对象
  type PartialPointX = {x: number}
  type PartialPointY = {y: number}
  // 联合类型
  type PartialPoint = PartialPointX | PartialPointY
  // 定义元组
  type dATA = [number,string]
扩展的方式不一样
  • 接口可以使用extends关键字来进行扩展(这个继承是包含关系,如果父级有了,子集不可以声明重复的,会报错的),或者使用implements来进行实现某个接口
  interface A {
    T1: string
  }
  interface B{
    T2: string
  }
  interface C extends A,B{
    T1:number
  }
  • 类型别名也可以进行扩展,使用&符号进行(这个继承是合并关系,如果父级有了一个类型,子集还可以声明,但是类型就是变成&)这个叫做交叉类型
type A = {
    T1: string
  }
  type B = {
    T2: string
  }
  type C = {
    T1: number
    T4: string
  } & A & B
  const test: C = {
    T1: '1', //  Type 'string' is not assignable to type 'never'.
    T2: '2',
    T4: 'dd'
  }

注意,类型别名可以声明形同属性为不同类型,但是在类型检查会类型推导成其他类型,这样使用可能会导致定义的类型和预期不符合

合并声明
  • 接口可以定义一个名字,后面的接口也可以直接使用这个名字,自动合并所有的声明,不建议这么使用,还是extends关键字好
  interface User2 {
    name1: string
  }
  interface User2 {
    age: number
  }
  const user: User2 = {
    name1: 'dd',
    age:12
  }
  • 类型别名不能重复定义相同名字,会直接报错
实例类型进行赋值
  • 接口没有这个功能
  • 类型别名可以使用typeof获取实例的类型进行赋值
let div = document.createElement('div')
  type D = typeof div
类型映射
  • 接口没有这个功能
  • 类型别名可以使用in来实现类型映射
 type keys = 'firstname' | 'lastname'
  type DudeType = {
    [key in keys] : string
  }
  const testss: DudeType = {
    firstname: '222',
    lastname: '333'
  }
最大的不同
  • 接口可以被类实现,而类型别名不可以
  • 接口是用来表达某个类是否拥有某种能力的,其实这就实现了接口
  • 接口可以实现继承类, 类型别名不可以
相同点
  • 都不会出现在编译结果里面
  • 两者都可以进行扩展
  • 都可以用来描述函数和对象
posted @ 2022-03-29 18:45  upupupupupgo  阅读(163)  评论(0编辑  收藏  举报