这个 return 类型从不做与只使用接口有什么区别?
What does this return type with never do vs just using an Interface?
在尝试用 Typescript 创建工厂时,我遇到了 this article,我对这部分感到困惑:
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);
I am not sure why we need ExtractInstanceType & why we don't want to just use IStaff?
因为 userMap
和关联的静态方法的重点是将名称映射到 具体的、具体的 classes,而不是它们的接口实行。如果这些 classes 中的任何一个在通用 IStaff 接口之上实现了 class-specific 的东西(他们几乎肯定会这样做),那么每次您的代码都会被 instanceof
或其他检查所困扰调用不在 IStaff
中的方法,如果您没有通过使用该静态方法缩小类型以满足编译器的要求,将其扼杀在萌芽状态。
I thought it was just one of the keys in the dictionary that userMap can hold, which would be a string?
正如我在对您 的回答的评论中所建议的那样,我认为问题在于您仍在混淆 types 和 values。 TBF 它没有帮助,有一些重叠。
考虑字符串 'a'。在 Typescript 中,有 value 'a' 但也有 literal 类型 '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
是一个 mutable 绑定到一个字符串,即使我们设置了 value 也不能用任何旧字符串索引 foo
到 'a',即使我们将它设置为 变量 a
具有 类型 a,s
是 still a string 编译器无法保证我们不会重新分配非 a 值。 playground
类型可能看起来像值,并且在某些上下文中可能与值具有完全相同的外观,但它们是不是值,值类型也不是。向右移动...
对于对象文字,我们在编译时知道对象中的键,所以如果我们有一个 foo 对象 {a: 'hi', b: 5}
,那么 keyof typeof foo
就是 'a' | 'b'
。 N.B。这些是字符串,但在本例中它们是 types,而不是 Javascript values。博客post中的方法限制了k
参数可以传递的值只能是userMap
.
的编译时已知键中的值
But when that method is used, is it is used with an object instance as it's parameter or is that not possible?
哦,可以改变方法以那样工作,这有点毫无意义。如果您有一个实例的引用,那么您已经有一个对其构造函数的引用,您不需要查找 table 来创建另一个:
class Foo {}
const foo = new Foo()
const bar = new (foo.constructor as any)()
bar instanceof Foo // true
同样,userMap
和访问它的静态方法的要点是工厂能够通过 字符串名称class 查找正确的用户 class =68=].
在尝试用 Typescript 创建工厂时,我遇到了 this article,我对这部分感到困惑:
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);
I am not sure why we need ExtractInstanceType & why we don't want to just use IStaff?
因为 userMap
和关联的静态方法的重点是将名称映射到 具体的、具体的 classes,而不是它们的接口实行。如果这些 classes 中的任何一个在通用 IStaff 接口之上实现了 class-specific 的东西(他们几乎肯定会这样做),那么每次您的代码都会被 instanceof
或其他检查所困扰调用不在 IStaff
中的方法,如果您没有通过使用该静态方法缩小类型以满足编译器的要求,将其扼杀在萌芽状态。
I thought it was just one of the keys in the dictionary that userMap can hold, which would be a string?
正如我在对您
考虑字符串 'a'。在 Typescript 中,有 value 'a' 但也有 literal 类型 '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
是一个 mutable 绑定到一个字符串,即使我们设置了 value 也不能用任何旧字符串索引 foo
到 'a',即使我们将它设置为 变量 a
具有 类型 a,s
是 still a string 编译器无法保证我们不会重新分配非 a 值。 playground
类型可能看起来像值,并且在某些上下文中可能与值具有完全相同的外观,但它们是不是值,值类型也不是。向右移动...
对于对象文字,我们在编译时知道对象中的键,所以如果我们有一个 foo 对象 {a: 'hi', b: 5}
,那么 keyof typeof foo
就是 'a' | 'b'
。 N.B。这些是字符串,但在本例中它们是 types,而不是 Javascript values。博客post中的方法限制了k
参数可以传递的值只能是userMap
.
But when that method is used, is it is used with an object instance as it's parameter or is that not possible?
哦,可以改变方法以那样工作,这有点毫无意义。如果您有一个实例的引用,那么您已经有一个对其构造函数的引用,您不需要查找 table 来创建另一个:
class Foo {}
const foo = new Foo()
const bar = new (foo.constructor as any)()
bar instanceof Foo // true
同样,userMap
和访问它的静态方法的要点是工厂能够通过 字符串名称class 查找正确的用户 class =68=].