我正在尝试为MainType
. 我还想重用已经创建的类型(实际上我需要相同的实例),所以我将它们存储在ItemFactory
.
class BaseType {
}
class MainType extends BaseType {
}
class ItemFactory {
items: { [type: string]: BaseType } = {};
get<T extends BaseType>(type: string): T | null {
let item = this.items[type];
if (!item) {
switch (type) {
case "main-type":
item = new MainType();
break;
default:
return null;
}
this.items[type] = item;
}
return item as T;
}
}
有没有办法简化通话
itemFactory.get<MainType>("main-type"); // current call
// option 1
const resolvedType = itemFactory.get<MainType>();
// option 2
const resolvedType = itemFactory.get("main-type");
我想要选项 1 或选项 2(两者都不需要),所以我不必同时传递标识符和类型来正确解析结果类型。
您需要在传递给的名称itemFactory.get()
和预期的输出类型之间为编译器提供某种映射。从名称到类型的映射是interface
s 最擅长的,因此您可以像这样定义一个:
interface NameMap {
"main-type": MainType;
// other name-type mappings here
}
然后你把你的get()
方法改成这样:
get<K extends keyof NameMap>(type: K): NameMap[K] | null {
let item = this.items[type];
if (!item) {
switch (type) {
case "main-type":
item = new MainType();
break;
default:
return null;
}
this.items[type] = item;
}
return item as NameMap[K];
}
你替换T extends BaseType
到NameMap[K]
where K extends keyof NameMap
。现在以下(“选项 2”)将起作用:
const resolvedType = itemFactory.get("main-type"); // MainType | null
请注意,您永远不会让“选项 1”起作用。当 JS 被发出时,TypeScript 的类型系统会被删除,所以这个:
itemFactory.get<MainType>();
将在运行时变成这样:
itemFactory.get();
有没有办法让该知道什么回报,因为相关资料已经落伍之前的代码开始运行。这是故意的;它是不是打字稿的目标为“在程序基于该类型系统的结果添加或依靠运行时类型信息,或发出不同的代码。” 相反,TypeScript 应该“鼓励不需要运行时元数据的编程模式”……在这种情况下,这意味着使用像字符串这样的运行时值"main-type"
而不是像MainType
跟踪get()
应该做什么的设计时类型。
好的,希望有帮助。祝你好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句