【发布时间】:2021-08-24 06:08:45
【问题描述】:
说,我有这些类和接口:
class Foo {}
interface Bar {}
我想创建这样一个type,它具有指定类型的属性名称:
type DynamicPropertyName<T> = ... <-- ???
那我想这样用:
type WithPropFoo = DynamicPropertyName<Foo>; // desire: {Foo: any}
type WithPropBar = DynamicPropertyName<Bar>; // desire: {Bar: any}
我将指定我的类型,而不是 any,这很简单。
第三条评论后更新
至少,也许有可能得到这个:
type WithPropFoo = DynamicPropertyName<Foo>; // desire: {type: 'Foo'}
type WithPropBar = DynamicPropertyName<Bar>; // desire: {type: 'Bar'}
const foo: WithPropFoo = {type: 'Foo'}; // ok
const foo: WithPropFoo = {type: 'Hello'}; // error
const foo: WithPropBar = {type: 'Bar'}; // ok
const foo: WithPropBar = {type: 'Hello'}; // error
【问题讨论】:
-
我发现这个答案stackoverflow.com/a/64933956 很有帮助。 @jcalz 也许您可以添加任何内容? =)
-
虽然@-提及不直接参与问题的人并没有做任何事情,但我在这里看到了这一点,这有点令人难过。无论如何,不,没有将类型的 name 转换为相应的字符串文字的编程方式。可以在运行时获得
"Foo",但不能在编译时获得(参见this question),但"Bar"完全无法访问。如果需要,您需要自己将这些字符串放在某个位置。 -
类型名称本质上是不可观察的。 TypeScript 有一个结构化的而非名义上的类型系统。如果您编写
interface A {x: 0}和interface B {x: 0},那么类型A和类型B是相同的类型,尽管有不同的声明。那么原则上,您不应该能够执行类型操作F<A>和F<B>并有两个不同的输出。如果这是有道理的,并且您对“不,抱歉”没有意见,我可以写一个答案。如果您真的想做其他事情,并且这就是您的想法,则可能是 XY 问题,您应该详细说明预期的用例。 -
@jcalz 请查看 UPD。不管这是否可能,如果你愿意,你可以写一个答案
标签: typescript typescript-generics template-literals