这是问题
interface Prop<T> {
value: T;
}
class Property<T> implements Prop<T> {
value: T;
constructor(value: T) {
this.value = value;
}
}
class Node {
this.props: { [index: string]: Prop<T> } // how do you define T?
}
T
无法在此级别定义为需要,因为预期用途将与
const strProp = node.props<string>['strProp'];
const numProp = node.props<number>['numProp'];
换句话说,Node
可以附加各种属性类型。
docs中似乎没有关于此事的任何内容(或者我只是没有看到它)。基本上我在这里真正需要的是通用索引器,例如:
this.props: <T>{ [index: string]: Prop<T> }
它存在吗?
免责声明 - 我不是在寻找解决方法,我知道有办法解决这个问题,但我想知道支持是否存在(我无法看到任何支持)关于回购的提案或未决问题)。有一些类似的问题,但没有具体的特定情况。
答案 0 :(得分:1)
不,在TypeScript中,只有函数(包括方法)和类型(类,接口,类型别名)可以是通用的。
此外,它看起来并不像你要求的实际上有多大意义。要了解原因,让我们看一下您不一定感兴趣的解决方法之一:
abstract class Node {
abstract propsGetter<T>(index: string): Prop<T>;
}
这里我们定义一个getter方法,它接受类型参数T
和string
参数,并返回类型Prop<T>
的值。这或多或少等同于索引属性。请注意,此方法的调用者,而不是实现者指定了类型T
和index
。
我想,你会这样称呼它:
declare const node: Node;
const strProp = node.propsGetter<string>('strProp');
const numProp = node.propsGetter<number>('numProp');
但是等等,没有什么可以阻止你这样称呼它:
const whatProp = node.propsGetter<string>('numProp'); // no error
如果您希望编译器以某种方式知道'numProp'
参数将返回Prop<number>
并且会出现错误,编译器会让您失望。 propsGetter
的签名承诺,无论Prop<T>
参数是什么,它都会为调用者想要的T
值返回index
。
除非你为编译器描述index
的类型(可能是一些字符串文字的集合)和T
的类型之间的某种关系,否则这里没有类型安全性。 type参数对你没有任何帮助。您也可以删除type参数,然后执行以下操作:
abstract class Node {
abstract propsGetter(index: string): Prop<{}>;
}
返回Prop<{}>
值,您必须键入check或assert:
const strProp = node.propsGetter('strProp') as Prop<string>; // okay
const numProp = node.propsGetter('numProp') as Prop<number>; // okay
这与上面的非类型安全一样,但至少它是明确的。
const whatProp = node.propsGetter('numProp') as Prop<string>; // still no error but it's your responsibility
然后,由于我们不需要泛型参数,您确实可以使用索引器:
class Node {
props: { [index: string]: Prop<{}> }
}
回想一下,
除非你为编译器描述
index
的类型(可能是一些字符串文字的集合)和T
的类型之间的某种关系,否则这里没有类型安全性。
您是否有某种方式告诉编译器哪些属性键应返回哪些属性类型?如果是这样,看起来你实际上并不想要一个纯string
- 索引类型,而是一个标准对象:
abstract class Node {
props: {
strProp: Prop<string>,
numProp: Prop<number>,
// ... others ...
[otherKeys: string]: Prop<{}> // default
}
}
也许其中一个符合您的使用案例......并非您关心,因为您的免责声明不承认。如果您不在乎,请在我的第一句话之后忽略所有内容。
希望有所帮助。祝你好运!