代码之家  ›  专栏  ›  技术社区  ›  GaryO

如何在查询脚本中安全地键入对象的类型属性?

  •  0
  • GaryO  · 技术社区  · 7 年前

    我想查询Typescript对象,看看它是否有属性。代码如下:

    class Base {
        x: number = 1
    }
    
    class DerivedA extends Base {
        y: number = 2
    }
    class DerivedB extends Base {
        y: number = 3
    }
    // and many more derived classes...
    
    function f(obj: Base) {
        console.log('x', obj.x)
        if ('y' in obj) {
            console.log('y', obj.y) // ERROR: property 'y' does not exist on type 'never'
        }
    }
    
    f(new Base())
    f(new DerivedA())
    

    (参见 playground )

    f 我想避免很多 instanceof DerivedA || instanceof DerivedB 因为可能有很多,而我忘了加新的。我想把它打出来,然后检查一下 y 财产。我可以用typescript来做这件事并避免错误吗?我必须这么做吗 (obj as any).y ?

    这似乎是一个更大的问题:如何将对象类型隐藏为已知基类的泛型派生类型?

    (我显然还在学习打字,以防不明显)

    0 回复  |  直到 7 年前
        1
  •  1
  •   SpencerPark    7 年前

    Typescript是在结构上键入的,因此签名 function f(obj: Base) function f(obj: {x: number}) . i、 你可以打电话来 f({x: 10}) 没问题,它不需要是 Base

    Typescript可以很好地缩小联合,这是解决问题的适当方法。我们确实需要在签名中捕获“所有”可能的参数形状,但这比一个长(并且可能会增加)的列表更容易 DerivedA | DerivedB . 我们可以像写形状一样 Base & {y?: number} Base | Base & {y: number} . 不要像对待Java或C等其他OO语言那样对待类,它们在这里的类型系统中表现得非常不同。

    表示对象将具有 x: number 可能是 y: number 我也是。然后用 'y' in obj ,typescript知道 obj 有场地吗 y 唯一的选择就是 'y' 具有类型 number if 打字治疗 目标 作为 Base & {y: number} . 您需要在函数体中编写一个只包含您所需内容的签名。

    推荐文章