我有一个基类:
class ClassA {
public prop1: string;
}
我有一个通用界面:
interface IMyInterface<T extends ClassA> {
objA: T;
}
一个通用类:
class MyClass<T extends ClassA> implements IMyInterface<T> {
public objA: T;
public myMethod () {
this.objA.prop1 = "foo"; // This is ok
if ("prop2" in this.objA) {
this.objA.prop2 = "bar"; // This is not
}
}
}
如果且仅当prop2
中存在此属性时,如何强制objA
objA
?
我是否必须强制演员(this.objA as ClassA & {prop2: string}).prop2 = "bar"
?
答案 0 :(得分:2)
这似乎是Typescript的当前限制。我发现this issue描述了这个确切的情况。
解决方法与您已经提到的相同。您必须将this.objA
转换为允许设置prop2
字段的其他类型。所以:
(this.objA as ClassA & {prop2: string}).prop2 = "bar"
// Or to trade some safety for brevity:
(this.objA as any).prop2 = "bar"
否则,您还可以使用自定义类型保护来断言该密钥的存在。使用上面链接的问题,你可以这样做:
function inOperator<K extends string, T>(k: K, o: T): o is T & Record<K, any> {
return k in o;
}
然后,使用它而不是in
运算符:
if (inOperator("prop2", this.objA)) {
this.objA.prop2 = "bar"; // No error now
}
答案 1 :(得分:1)
您可以在Type Guards and Differentiating Types
会话中使用类型保护,如here所述
您的代码将如下所示:
class ClassA {
public prop1: string;
}
interface IMyInterface<T extends ClassA> {
objA: T;
}
interface IProp2 {
prop2: string;
}
function hasProp2(obj: ClassA | IProp2): obj is IProp2 {
return (<IProp2>obj).prop2 !== undefined;
}
class MyClass<T extends ClassA> implements IMyInterface<T> {
public objA: T;
public myMethod () {
this.objA.prop1 = "foo"; // This is ok
if (hasProp2(this.objA)){
this.objA.prop2 = "bar"; // Now this is ok
}
}
}