类型断言
通过 类型断言 可以告诉编辑器: 相信我,我知道自己在干什么。类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript 会假设你,程序员,已经进行了必须的检查。
// 第一种: 尖括号 语法
let someValue: any = 'this is a string';
let strLength: number = (<string>someValue).length;
console.log('strLength', strLength);
// 第二种: as 语法
let someValue2: any = 'this is a string';
let strLength2: number = (someValue2 as string).length;
console.log('strLength2', strLength2);
类型别名
类型别名用来给一个类型起个新名字。使用 type
创建类型别名,常用于联合类型。
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}
字符串字面量类型
适合用来约束取值只能是某个字符串的其中一个。注意,类型别名与字符串字面量类型都是使用 type
进行定义。
type EventNames = "Click" | "Scroll" | "MouseMove";
function handleEvent(event: EventNames) {
console.log(event);
}
// 取值只能为 "Click" | "Scroll" | "MouseMove" 其中一个
handleEvent("Scroll");
元祖Tuple和枚举
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为string
和number
类型的元组。
let tom: [string, number] = ['Tom', 25];
枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。使用 enum
关键字来定义。
枚举成员默认会被赋值为从 0
开始递增的数字,同时也会对枚举值到枚举名进行反向映射:
enum Days {
Sun,
Mon,
Tue,
Wed,
Thu,
Fri,
Sat,
}
console.log(Days["Sun"] === 0); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true
console.log(Days[0] === "Sun"); // true
console.log(Days[1] === "Mon"); // true
console.log(Days[2] === "Tue"); // true
console.log(Days[6] === "Sat"); // true
手动赋值
手动赋值的枚举项会接着上一个枚举项递增。
enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
console.log(Days["Sun"] === 7); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true
字符串枚举
enum Person {
name = "NAME",
age = "AGE",
love = "LOVE",
hobby = "HOBBY"
}
console.log(Person.name) // NAME
console.log(Person.hobby) // HOBBY
异构枚举
enum Person {
name = 1,
age = 2,
love = "LOVE",
hobby = "HOBBY"
}
console.log(Person.name) // 1
console.log(Person.hobby) // HOBBY
常量枚举
常量枚举通过在枚举上使用 const
修饰符来定义,常量枚举不同于常规的枚举,他们会在编译阶段被删除。
const enum Size {
WIDTH = 10,
HEIGHT = 20
}
const area = Size.WIDTH * Size.HEIGHT
// 常量枚举成员在使用的地方会被内联进来,之所以可以这么做是因为,常量枚举不允许包含计算成员;如上例所示,在运行时是没有 Size
泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
function createArray(length: number, value: any): Array<any> {
let result = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
console.log(createArray(5, "A"));
这段代码编译不会报错,但是一个显而易见的缺陷是,它并没有准确的定义返回值的类型:
Array<any>
允许数组的每一项都为任意类型。但是我们预期的是,数组中每一项都应该是输入的 value
的类型。
这时候,泛型就派上用场了:
function createArray<T>(length: number, value: T): Array<T> {
let result = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
console.log(createArray<string>(5, "A"));
// 也可以不指定,通过类型推论也可以自动推算出来
console.log(createArray(5, "A"));
泛型约束
在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法
function loggingIdentiy<T>(arg: T): T {
// 编辑器提示:类型“T”上不存在属性“length”
console.log(arg.length)
return arg
}
上例中,泛型 T
不一定包含属性 length
,所以编译的时候报错了。
这时,我们可以对泛型进行约束,只允许这个函数传入那些包含 length
属性的变量。这就是泛型约束
// string 类型中有 length 属性
function loggingIdentiy<T extends string>(arg: T): T {
console.log(arg.length);
return arg;
}
// 或者是继承相关的接口
interface ILength {
length: number
}
function loggingIdentiy<T extends ILength>(arg: T): T {
console.log(arg.length);
return arg;
}
泛型函数接口
interface ConfigFn {
<T>(value: T): T;
}
var getData: ConfigFn = (value) => {
return value;
}
console.log(getData<string>('张三'))
// 提示:类型“number”的参数不能赋给类型“string”的参数
console.log(getData<string>(1))
泛型类
class GetMin<T>{
arr: T[] = [];
add(ele: T) {
this.arr.push(ele)
}
min(): T {
var min = this.arr[0];
this.arr.forEach(value => {
if (value < min) {
min = value
}
})
return min
}
}
var gm1 = new GetMin<number>();
gm1.add(5)
gm1.add(2)
gm1.add(3)
gm1.add(1)
console.log(gm1.min()) // 1
var gm2 = new GetMin<string>();
gm2.add("tom");
gm2.add("jerry");
gm2.add("jack");
gm2.add("sunny");
console.log(gm2.min()) // jack
泛型参数的默认类型
在 TypeScript 2.3 以后,我们可以为泛型中的类型参数指定默认类型。当使用泛型时没有在代码中直接指定类型参数,从实际值参数中也无法推测出时,这个默认类型就会起作用
function createArray<T = string>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}