将对象文字转换为子接口

时间:2018-03-20 17:42:58

标签: typescript

请查看以下代码:typescript playground(打开interface A { get(): number; } class Smth1 { public x: A = { value: 2, get() { return this.value } } } class Smth2 { public x: A = { value: 2, get() { return this.value } } as A } class Smth3 { public x: A constructor() { const x = { value: 2, get() { return this.value } } this.x = x } } 标志)

Smth1

Smth2public x: A = { value: 2, get() { return this.value } } 都有编译错误:

public x: A = { value: 2, get() { return this.value } } as A
  

对象文字只能指定已知属性,'a'类型中不存在'value'。

     

“A”类型中不存在属性“值”。

Smth3
  

“A”类型中不存在属性“值”。

只有as any没有编译错误。

这意味着我必须为我的类添加显式构造函数并将赋值拆分为两个语句:临时变量并将其分配给类字段。

至于我,这似乎有很多代码。

如何在不使用{{1}}的情况下将具有额外字段的对象文字指定为接口类型?

2 个答案:

答案 0 :(得分:3)

在没有额外接口的情况下执行此操作的方法是使用辅助函数。这解决了对象文字只能指定已知属性的错误,但它维护了A和json文字之间兼容性的完整类型检查。 :

function objectLiteral<T>(v: T) : T{
    return  v;
}

class Smth1 {
    public x: A = objectLiteral({ value: 2, get() { return this.value } })
}

您仍然需要定义一个额外的实体,但至少它是可重用的。

修改

一种无功能的方法,将是一个额外的字段/变量,它的工作方式与推断_x的方式非常相似,然后在分配给x时检查兼容性:

class Smth2 {
    private _x ={ value: 2, get() { return this.value } };
    public x: A = this._x;
}

或者没有明确定义函数,使用自执行函数。

class Smth2 {
    public x: A = (() => ({ value: 2, get() { return this.value } }))();
}

答案 1 :(得分:2)

您需要声明一个具有该属性的单独子类型,以便TypeScript将您的this识别为具有该属性的类型:

interface AWithValue extends A { value: number; }
class Smth2 {
  public x: A = { value: 2, get() { return this.value } } as AWithValue
}

Demo