typescript - 与只使用接口相比,这种返回类型从不做什么?
问题描述
在尝试在 Typescript 中创建工厂时,我遇到了这篇文章,对此部分感到困惑:
class UserFactory {
static getUser(k: Keys) : ExtractInstanceType<userTypes> {
return new userMap[k]();
}
类型定义供参考:
type ExtractInstanceType<T> = T extends new () => infer R ? R : never;
我不确定我们为什么需要ExtractInstanceType 以及为什么我们不想只使用 IStaff:
class UserFactory {
static getUser(k: Keys) : IStaff {
return new userMap[k]();
}
我也对 Keys 在这里所说的内容感到困惑,我认为它只是 userMap 可以保存的字典中的一个键,它是一个字符串?
但是,当使用该方法时,它是与对象实例一起用作参数还是不可能的?
const manager = new Manager();
const anotherManger = UserFactory.getUser(manager);
解决方案
我不确定我们为什么需要 ExtractInstanceType 以及为什么我们不想只使用 IStaff?
因为userMap
和相关的静态方法的重点是将名称映射到特定的具体类,而不是它们实现的接口。如果这些类中的任何一个在通用 IStaff 接口之上实现了特定于类的东西(而且它们几乎肯定会),那么instanceof
每次你调用一个方法时,IStaff
如果你没有将它扼杀在通过使用该静态方法缩小类型以满足编译器的要求。
我以为它只是 userMap 可以保存的字典中的一个键,它是一个字符串?
正如我在对您的其他问题的回答的评论中所建议的那样,我认为问题在于您仍在混淆类型和值。TBF 它没有帮助,有一些重叠。
考虑字符串'a'。在 Typescript 中,有值'a' 但也有文字类型 'a',它是 type 的子集string
:
type a = 'a'
let a: a = 'a'
let s: string = a // note, variable a not string literal a!
const foo = {
a: 1
}
console.log(foo[a]) // 1
console.log(foo[s]) // type error!
// ok, let's try the string literal 'a'
s = 'a'
console.log(foo[s]) // same type error!
// eff
由于a
字面上是“a”,我们可以foo
用它来索引。But是对字符串的可变绑定,即使我们将值设置为 'a',s
您也不能使用任何旧字符串进行索引,即使我们将其设置为类型为 a的变量,编译器仍然是字符串无法保证我们不会重新分配非 a 值。操场foo
a
s
类型可能看起来像值,并且在某些上下文中可能具有与值完全相同的外观,但它们不是值,也不是值类型。一直往前走……
对于对象字面量,我们在编译时就知道对象中的键,所以如果我们有一个 foo 对象,{a: 'hi', b: 5}
那么keyof typeof foo
is 'a' | 'b'
。注意那些是字符串,但在这种情况下它们是类型,而不是 Javascript值。博客文章中的方法将k
参数可以传递的值限制为仅在userMap
.
但是,当使用该方法时,它是与对象实例一起用作参数还是不可能的?
哦,可以改变方法以使其工作,这有点毫无意义。如果您有一个实例的引用,那么您已经有一个对其构造函数的引用,您不需要查找表来创建另一个:
class Foo {}
const foo = new Foo()
const bar = new (foo.constructor as any)()
bar instanceof Foo // true
同样,userMap
访问它的静态方法的意义在于工厂能够通过字符串名称查找正确的用户类。
推荐阅读
- java - JavaFX:有没有办法在 LineChart 中添加中断?
- r - 计算两列中的值都为真的行数
- visual-studio-code - “rm:无法删除'wslServer.sh':没有这样的文件或目录”
- javascript - 我的按钮只能点击一次。我希望能够重复多次搜索
- python - 如何将 kivy 中的 Dropdow 列表与主按钮的中心对齐?
- javascript - 立即调用的函数调用 setTimeout 调用循环
- vb.net - Stream.Read 上的 exe 文件
- keras - 微调自定义keras模型
- sql-server - 使用动态 SQL 将 XML 字符串展平为 SQL 表
- react-native - react-navigation:这真的是访问兄弟和父导航器的唯一方法吗?