function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key]
}
let x = {a: 1, b: 2, c: 3, d: 4}
getProperty(x, "a")
getProperty(x,"m") // Error TS2345: Argument of type '"m"' is not assignable to parameter of type '"a" | "b" | "c" | "d"'.
1、上面的代码中,设定泛型函数 getProperty 的参数 obj的类型为变量 T表示的类型,参数 key 的类型为 变量 K表示的类型。
2、 K extends keyof T 表示 K 应该是T的键值。
3、"a"是x的一个键值,所以 getProperty(x, "a")调用是OK的。
4、"m"不是 x 的一个键值,所以 getProperty(x,"m") 调用会报错。
在泛型中使用类类型
function create<T>(c: {new(): T; }): T {
return new c();
}
1、上面的代码中,c 表示一个构造函数,create 返回一个实例,所以 T 表示 一个实例,是一个表示实例的变量。
2、create 函数的参数 c 的类型是一个构造函数,用来描述这个构造函数的泛型函数是: {new (): T;},也可以表示为: new () => T。
总结,下面两种写法都可以:
方式一:
function create<T>(c: { new(): T }): T {
return new c()
}
方式二:
function create<T>(c: new () => T): T {
return new c()
}
原文地址:http://www.typescriptlang.org/docs/handbook/generics.html
泛型约束
在下面这个泛型函数中,因为不确定参数 arg 一定会有 length 属性,所以Ts 报错:
可以给T设置一些限制,使它具备 length 属性,通过创建一个描述约束的接口来实现:
因为现在泛型函数 loggingIdentity 受到了限制,它不能再接收任何类型的参数,所以下面的调用会报错:
我们只能传一些具有约束中指明的属性的值到 loggingIdentity ,才能通过 Ts 编译器的检查。
在泛型约束中使用“类型参数”
参数类型变量 可以受其他参数类型变量 的约束。比如:
1、上面的代码中,设定泛型函数 getProperty 的参数 obj的类型为变量 T表示的类型,参数 key 的类型为 变量 K表示的类型。 2、
K extends keyof T
表示 K 应该是T的键值。 3、"a"是x的一个键值,所以 getProperty(x, "a")调用是OK的。 4、"m"不是 x 的一个键值,所以 getProperty(x,"m") 调用会报错。在泛型中使用类类型
1、上面的代码中,c 表示一个构造函数,create 返回一个实例,所以 T 表示 一个实例,是一个表示实例的变量。 2、create 函数的参数 c 的类型是一个构造函数,用来描述这个构造函数的泛型函数是:
{new (): T;}
,也可以表示为:new () => T
。总结,下面两种写法都可以: 方式一:
方式二:
如下图所示: