这个返回类型永远不做什么与只使用接口?



在尝试用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]();
}

我也很困惑,键在这里说什么,我认为这只是一个键在字典中,userMap可以持有,这将是一个字符串?

但是当使用该方法时,它是与对象实例一起使用作为它的参数还是不可能?

const manager = new Manager();
const anotherManger = UserFactory.getUser(manager);

我不知道为什么我们需要ExtractInstanceType &为什么我们不想只用IStaff呢?

因为userMap和关联的静态方法的重点是将名称映射到特定的、具体的类,而不是它们实现的接口。如果这些类中的任何一个在通用的IStaff接口之上实现了特定于类的东西(它们几乎肯定会),如果你没有通过缩小静态方法的类型来满足编译器,那么每次调用不在IStaff中的方法时,你的代码就会被instanceof或其他检查弄得乱七八糟。

我认为它只是字典中userMap可以保存的键之一,这将是一个字符串?

正如我在回答你的另一个问题的评论中所建议的那样,我认为问题是你仍然将类型混为一谈。总而言之,有一些重叠并没有帮助。

考虑字符串'a'。在Typescript中,有'a',但也有文字类型'a',它是类型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。但是s是一个可变的字符串绑定,你不能用任何旧字符串索引foo,即使我们将设置为'a',即使我们将它设置为变量a,它的类型是as仍然是对于字符串,编译器无法保证不会重新赋值非A值。操场上

类型可能看起来像值,并且在某些上下文中可能具有与值完全相同的外观,但是它们是而不是值,也不是值类型。

对于对象字面值,我们在编译时知道对象中的键,所以如果我们有一个foo对象{a: 'hi', b: 5},那么keyof typeof foo就是'a' | 'b'。注意:这些都是字符串,但在这种情况下,它们是类型,而不是Javascript。博客文章中的方法将k参数可以传递的值限制为userMap的编译时已知键中的值。

但是当使用该方法时,它是与对象实例一起用作参数还是不可能?

哦,可以改变方法以这种方式工作,这有点毫无意义。如果你有一个实例的引用,你已经有一个对它的构造函数的引用,你不需要一个查找表来创建另一个:

class Foo {}
const foo = new Foo()
const bar = new (foo.constructor as any)()
bar instanceof Foo // true

游乐场

同样,userMap和访问它的静态方法的目的是让工厂能够通过字符串名称查找正确的用户类。

相关内容

  • 没有找到相关文章

最新更新