转载node
项目实践仓库git
https://github.com/durban89/typescript_demo.git tag: 1.3.4
为了保证后面的学习演示须要安装下ts-node,这样后面的每一个操做都能直接运行看到输出的结果。github
npm install -D ts-node
后面本身在练习的时候能够这样使用typescript
npx ts-node 脚本路径
我以前分享的一个例子中,有时候想操做某类型的一组值,而且知道这组值具备什么样的属性。在loggingIdentity例子中,咱们想访问arg的length属性,可是编译器并不能证实每种类型都有length属性,因此就报错了。npm
function loggingIdentity<T>(arg: T): T { console.log(arg.length); // Error: T doesn't have .length return arg; }
相比于操做any全部类型,咱们想要限制函数去处理任意带有.length属性的全部类型。 只要传入的类型有这个属性,咱们就容许,就是说至少包含这一属性。 为此,咱们须要列出对于T的约束要求。为此,咱们定义一个接口来描述约束条件。 建立一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束:函数
interface LengthDefine { length: number; } function loggingIdentity<T extends LengthDefine>(arg: T): T { console.log(arg.length); return arg; }
如今这个泛型函数被定义了约束,所以它再也不是适用于任意类型:学习
loggingIdentity(3);
运行后会遇到以下错误提示spa
⨯ Unable to compile TypeScript: src/generics_5.ts(11,17): error TS2345: Argument of type '3' is not assignable to parameter of type 'LengthDefine'.
咱们须要传入符合约束类型的值,必须包含必须的属性:code
loggingIdentity({length: 10, value:3});
运行后会获得以下结果对象
$ npx ts-node src/generics_5.ts 10
咱们能够声明一个类型参数,且它被另外一个类型参数所约束。 好比,如今咱们想要用属性名从对象里获取这个属性。 而且咱们想要确保这个属性存在于对象 obj上,所以咱们须要在这两个类型之间使用约束。
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"); // 异常
运行后获得以下错误信息
$ npx ts-node src/generics_5.ts ⨯ Unable to compile TypeScript: src/generics_5.ts(21,16): error TS2345: Argument of type '"m"' is not assignable to parameter of type '"a" | "b" | "c" | "d"'.
在TypeScript使用泛型建立工厂函数时,须要引用构造函数的类类型。好比,
function create<T> (c: {new(): T;}): T { return new c(); }
一个更高级的例子,使用原型属性推断并约束构造函数与类实例的关系。
class Keeper1 { hasMask: boolean; } class Keeper2 { nameTag: string; } class Keeper3 { numLength: number; } class ChildrenKeeper1 extends Keeper3 { keeper: Keeper1; } class ChildrenKeeper2 extends Keeper3 { keeper: Keeper2; } function createInstance<A extends Keeper3> (c: new() => A): A { return new c(); } console.log(createInstance(ChildrenKeeper1)); console.log(createInstance(ChildrenKeeper2));
运行后获得以下输出
$ npx ts-node src/generics_5.ts ChildrenKeeper1 {} ChildrenKeeper2 {}
感受没在实际应用中使用,很鸡肋呀
本实例结束实践项目地址
https://github.com/durban89/typescript_demo.git tag: 1.3.5