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的区别
不同点
语法上
type
和interface
的语法不一样,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'
}
最大的不同
- 接口可以被类实现,而类型别名不可以
- 接口是用来表达某个类是否拥有某种能力的,其实这就实现了接口
- 接口可以实现继承类, 类型别名不可以
相同点
- 都不会出现在编译结果里面
- 两者都可以进行扩展
- 都可以用来描述函数和对象