代码之家  ›  专栏  ›  技术社区  ›  matt helliwell

键入guards将接口X转换为所需的<X>[[副本]

  •  0
  • matt helliwell  · 技术社区  · 3 年前

    Foo Required<Foo> . 是否有一种类型安全的方法来调用此函数?例如

    interface FooBar {foo:string, bar?: string}
    
    const myFooBar:FooBar = {foo:'foo'}
    if (myFooBar.bar !== undefined) {
        test(myFooBar)
    }
    
    function test(fooBar: Required<FooBar>) {
        console.log(fooBar.bar)
    }
    

    但是编译器报告

    Argument of type 'FooBar' is not assignable to parameter of type 'Required<FooBar>'.
      Types of property 'bar' are incompatible.
        Type 'string | undefined' is not assignable to type 'string'.
          Type 'undefined' is not assignable to type 'string'.(2345)
    

    连结至游乐场: https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgGIHt0CE5WQbxkwC4BnMKUAcwBpkAjXAfmOXMpCoF8AoHhdCHLIAtgE8M2XMUk48AXgJF0xAOTLVvYDGQAKcbNwA6RngCE8xQFcQAEwgxQEWwEoCPZJ+SRy+iZjkXHl4eGBsEMGBBbwhfZTlWACUIAEcrYChnAB5DKAA+N3wPLwEhdAAbCCNy9CpdeONTIN4gA

    1 回复  |  直到 3 年前
        1
  •  1
  •   T.J. Crowder    3 年前

    你可以使用 type guard function 为此:

    function hasBar(fooBar: FooBar): fooBar is Required<FooBar> {
        return typeof myFooBar.bar !== "undefined";
    }
    

    然后

    if (hasBar(myFooBar)) {
        test(myFooBar)
    }
    

    Playground link

    FooBar 如果您不想输入,请键入。这可能是特定于以下事实: bar 是类型 string

    function hasBarString<T>(fooBar: T): fooBar is T & {bar: string} {
        return typeof myFooBar.bar === "string";
    }
    
    const myFooBar:FooBar = {foo:'foo'}
    if (hasBarString(myFooBar)) {
        test(myFooBar)
    }
    

    Playground link