我们可以通过
type去声明一个类型别名
- 接口可以在
extends或implements子句中命名,但对象类型文字的类型别名不能命名。 - 接口可以有多个合并声明,但对象类型文字的类型别名不能.
- 一般来说,如果不清楚什么时候用
interface/type,能用interface实现,就用interface, 如果不能就用type
联合类型
联合类型就是将两个类型联合起来,只要两者符合其中一者就可以,用|做连接
type testType=string|number
const test=(x:testType):testType=>x
console.log(test(1)) //1
console.log(test('test')) //test
console.log(test([1])) //类型“number[]”的参数不能赋给类型“testType”的参数
交叉类型
交叉类型就是类型与类型合并,两个都要符合,用&做连接
interface test1 {
X: number;
}
interface test2 {
Y: number;
}
type testType = test1 & test2;
const test = (x: testType): testType => x;
console.log(test({ X: 1, Y: 2 }));
console.log(test({ X: 1})); //类型“{ X: number; }”中缺少属性“Y”
类型保护与区分类型
当我们使用联合类型作为函数的返回值,要使用返回值里的方法会被如果不是两个类型里共有的,会被推断为没有该属性,这是因为ts的类型保护,这种情况我们可以使用类型断言
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird {
// ...
}
let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim(); // error
if ((<Fish>pet).swim) {
(<Fish>pet).swim();
} else {
(<Bird>pet).fly();
}
用户自定义的类型保护
要定义一个类型保护,我们只要简单地定义一个函数,它的返回值是一个 类型谓词:
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getSmallPet(): Fish | Bird {
// ...
}
//自定义类型保护
function isFish(pet: Fish | Bird): pet is Fish {
return (<Fish>pet).swim !== undefined;
}
let pet = getSmallPet();
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
在上面的例子用isFish定义了自定义类型保护,返回值pet is Fish就是类型谓词,TypeScript不仅知道在 if分支里 pet是 Fish类型; 它还清楚在 else分支里,一定 不是 Fish类型,一定是 Bird类型。
字面量类型
我们可以使用字符串作为类型去使用
type state='signIn'|'Logout';
function isSignIn(user:state):boolean{
return user==='signIn'?true:false
}
数字字面量类型道理也是一样的
可辨识联合
可辨识联合类型概念
- 具有普通的单例类型属性— 可辨识的特征。
- 一个类型别名包含了那些类型的联合— 联合。
- 此属性上的类型保护。
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Rectangle | Circle;
function area(s: Shape) {
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.height * s.width;
case "circle": return Math.PI * s.radius ** 2;
}
}
多态的 this类型
多态的this就是会在每个操作之后都会返回this实例
class Num{
constructor(public val:number){
this.val=val
}
add(x):this{
this.val+=x
return this
}
minus(x):this{
this.val-=x
return this
}
}
console.log(new Num(1).add(2).minus(1).val) //2
索引类型
可以通过keyof关键字去提取类型中的key值
interface Type{
x:string,
y:string,
z:string
}
type X= keyof Type //type X = "x" | "y" | "z"
映射类型
interface Type{
x:string,
y:string,
z:string
}
type Readonly<T>={
readonly [p in keyof T]: T[p]
}
type X=Readonly<Type> // X = { readonly x: string; readonly y: string; readonly z: string; }
上面的例子我们通过Readonly<T>类型里面通过in关键字便利keyof T里的值,给每一个属性添加上readonly属性
预定义的有条件类型
TypeScript 2.8在lib.d.ts里增加了一些预定义的有条件类型:
Exclude<T, U>-- 从T中剔除可以赋值给U的类型。Extract<T, U>-- 提取T中可以赋值给U的类型。NonNullable<T>-- 从T中剔除null和undefined。ReturnType<T>-- 获取函数返回值类型。InstanceType<T>-- 获取构造函数类型的实例类型。
type Type="a" | "b" | "c" | "d"
type T01=Exclude<Type,'a'> //"b" | "c" | "d"
type T02=Extract<Type,'a'> //"a"
type T03 = NonNullable<string | number | undefined> //string|number
type T04 = ReturnType<() => string>;//string
function f1(s: string) { return { a: 1, b: s }; }
type T05 = ReturnType< typeof f1> //{ a: 1, b: s }
class C {
x = 0;
y = 0;
}
type T06 = InstanceType<typeof C>; // C