编辑,这是我用来解释该问题的实际代码:
https://gist.github.com/LukasBombach/7bf255392074509147a250b448388518
使用TypeScript我想指定一个泛型,它是普通对象的任何数据结构
class MyClass<T extends {}> {
public vars: T;
constructor() {
this.vars = {};
}
}
所以我可以做
interface MyType {
foo: string;
bar: number;
}
new MyClass<MyType>()
或
interface MyType {
baz: string;
boo: {
bam: Function;
bix: number;
};
}
new MyClass<MyType>()
我在那里建议的实现无法正常工作,但出现错误:
class MyClass<T extends {}> {
public vars: T;
constructor() {
this.vars = {};
// ^^^^
}
}
Type '{}' is not assignable to type 'T'. '{}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.ts(2322)
答案 0 :(得分:1)
将vars
的类型定义为Partial<T>
class MyClass<T> {
public vars: Partial<T>;
constructor() {
this.vars = {};
}
}
这告诉TypeScript所有属性都是可选。
const x = new MyClass<MyType>();
console.log(x.vars.foo); // prints "undefined" but there is no TS error
console.log(x.vars.thing); // prints "undefined" but TS error for unknown property.
https://netbasal.com/getting-to-know-the-partial-type-in-typescript-ecfcfbc87cb6
类型为 partial 时,始终为 partial 。您将收到以下警告。
const x: Partial<FooBar> = {};
const y: FooBar = x; // TS error, because x is partial.
您可以通过强制转换分配。
const y: FooBar = x as FooBar;
这里的事情是,您已经将变量定义为 partial 。因此, true 是您永远不会知道它是否真正填充了值。
您可以使用运行时类型验证程序来检查:
export function isMyType(value: any): value is MyType {
return typeof value['foot'] === 'string'
&& typeof value['bar'] === 'number';
}
const x: Partial<MyType> = {};
if(isMyType(x)) {
const y: MyType = x; // there is no TS, because of the isMyType check
}
我忘记了TypeScript中的is
运算符被称为什么,但是当在条件块中使用时,用于检查变量的 type 发生了变化。因此TypeScript不会对此抱怨。
如果该值不是您认为的应有的值,它还可以引发运行时错误。
答案 1 :(得分:0)
错误完全符合逻辑。
使用您的第一个示例MyType
,这等效于MyClass
,没有通用名称:
interface MyType {
foo: string;
bar: number;
}
class MyClass {
public vars: MyType;
constructor() {
this.vars = {};
}
}
由于vars
现在必须具有foo
和bar
成员,因此不允许分配vars = {}
。
答案 2 :(得分:0)
我认为这可能会解决
class MyClass<T extends {[key:string]: any}> {
public vars: T;
constructor() {
this.vars = {};
}
}
例如:
interface MyType {
foo: string;
bar: number;
}
let test = new MyClass<MyType>();
在测试中,您将能够找到MyType类型的var,而在test.vars中,您可以看到foo和bar属性可用