typescript - TypeScript 中具有泛型的默认参数
问题描述
考虑 TypeScript 文档中的最后一个泛型示例: https ://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-generics
如果我想为我将如何执行此操作Lion
设置默认值?createInstance()
例如:
class Animal {
numLegs: number = 0;
}
class Lion extends Animal {
keeper = "zookeeper";
}
function createInstance<A extends Animal>(c: new () => A = Lion): A { // error!
// -------------------------------------> ~~~~~~~~~~~~~~~~~~~~~
// 'Lion' is assignable to the constraint of type 'A', but 'A' could be
// instantiated with a different subtype of constraint 'Animal'.
return new c();
}
解决方案
您可以使用泛型参数默认值和类型断言来告诉编译器缺乏对A
意味着A
is的推断Lion
,并且可以做出这样的假设:
function createInstanceAssert<A extends Animal = Lion>(c: new () => A = Lion as any) {
return new c();
}
我认为这将在您的用例中按需要工作:
createInstanceAssert(Lion).keeper.nametag;
createInstanceAssert(Bee).keeper.hasMask;
createInstanceAssert().keeper.nametag;
虽然有可能有人手动指定泛型参数并造成麻烦:
createInstanceAssert<Bee>().keeper.hasMask.valueOf(); // compiles, but error at runtime
// ---------------> ~~~~~ don't do this, okay?
这可能不太可能,但您应该意识到这一点。
如果您真的想防止误用,可以使用重载来区分两个单独的用例:
function createInstanceOverload<A extends Animal>(c: new () => A): A;
function createInstanceOverload(): Lion;
function createInstanceOverload(c: new () => Animal = Lion) {
return new c();
}
您基本上可以使用参数调用它,在这种情况下它是通用的并且A
是推断的,或者您可以不带参数调用它,在这种情况下它不是通用的,并且Lion
出现:
createInstanceOverload(Lion).keeper.nametag;
createInstanceOverload(Bee).keeper.hasMask;
createInstanceOverload().keeper.nametag;
由于没有通用的零参数调用签名,因此在没有大的编译器错误的情况下不再可能进行以下操作:
createInstanceOverload<Bee>().keeper.hasMask.valueOf(); // error at compile time
推荐阅读
- python - 生成子进程的固定计数直到结束 -python3
- python - 在折线图中绘制连续色标
- python - 如果输入字符串 id 太长或有段落,则不会全部复制
- javascript - 更改当前元素的颜色并从上一次单击中删除背景
- google-chrome - Cant hide columns in chrome dev tools network tab
- python - 基于目标变量的编码技术预测看不见的数据
- powershell - 在备份文件夹中编辑新文件并将其移动到另一个文件夹
- python - 将函数应用于多个列表的每个元素;返回不同名称的数据框
- vue.js - Vue 单文件组件导入生命周期钩子
- python - 如何创建与大多数列匹配的 Pandas 列?