一、类型别名
? ? ? ? 概念:类型别名用来给一个类型起个新名字,使用?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 ?定了一个字符串字面量类型?EventNames ,它只能取三种字符串中的一种,类型别名与字符串字面量类型都是使用?type ?进行定义。
例子:
type EventNames = 'click' | 'scroll' | 'mousemove';
function handleEvent(ele: Element, event: EventNames) {
// do something
}
handleEvent(document.getElementById('hello'), 'scroll'); // 没问题
handleEvent(document.getElementById('world'), 'dblclick'); // 报错,event 不能为 'dblclick'
// index.ts(7,47): error TS2345: Argument of type '"dblclick"' is not assignable to parameter of type 'EventNames'.
三、泛型
概念:泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
例子:
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray<string>(3, 'x'); // ['x', 'x', 'x']
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}
swap([7, 'seven']); // ['seven', 7]
?why?
在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的? 属性或方法。
function loggingIdentity<T>(arg: T): T {
console.log(arg.length);
return arg;
}
? ? ? ?之前学习过,可以使用接口的方式来定义一个函数需要符合的形状:
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
????????当然也可以使用含有泛型的接口来定义函数的形状:
interface CreateArrayFunc {
<T>(length: number, value: T): Array<T>;
}
let createArray: CreateArrayFunc;
createArray = function<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray(3, 'x'); // ['x', 'x', 'x']
????????进一步,我们可以把泛型参数提前到接口名上(注意,此时在使用泛型接口的时候,需要定义泛型的类型):
interface CreateArrayFunc<T> {
(length: number, value: T): Array<T>;
}
let createArray: CreateArrayFunc<any>;
createArray = function<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray(3, 'x'); // ['x', 'x', 'x']
????????与泛型接口类似,泛型也可以用于类的类型定义中:
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
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;
}
|