打字稿无法根据可选属性缩小Union

问题描述

我在缩小打字稿中的联合类型时遇到问题。

假设我们有两个接口和一个联合:

interface A {
    flag: true
    callback: (arg: string) => void
}

interface B {
    flag?: false
    callback: (arg: number) => void
}

type AB = A | B

可以正确缩小范围:

const testA: AB = {
    flag: true,callback: arg => {
        // typescript knows this is interface A and arg is a string
    }
}

const testB: AB = {
    flag: false,callback: arg => {
        // typescript knows this is interface B and arg is a number
    }
}

但这不起作用:

const testC: AB = {
    // we are implying flag: undefined
    callback: arg => {
        // typescript has no clue if this is A or B
        // arg is implicitly any
    }
}

我想念什么?

这里是typescript playground

的链接

预先感谢

解决方法

flag ?:声明可能没有值。

flag ?: false等于标志:false |未定义,并非没有flag属性。

message MyMeta {
  optional bool needValidation = 1;

  message FileMapEntry {
    string key = 1;
    string value = 2;
  }
  repeated FileMapEntry fileMap = 2;
}
,
// Error on testC,[...] 'number' is not assignable to type 'string'
const testC: AB = {
  flag: undefined,callback: (arg: string) => {
  }
}

// same error
const testC: AB = {
  callback: (arg: string) => {
  }
}

有趣的是:

interface B {
  flag: false | undefined;
  callback: (arg: number) => void
}

// Type '{ callback: (arg: any) => void; }' is not assignable to type 'AB'.
//   Property 'flag' is missing in type '{ callback: (arg: any) => void; }' but required in type 'B'.
const testC: AB = {
  callback: (arg) => {
  }
}

我不知道Typescript应该以不同的方式处理flag?flag: undefined。但是可能与一个奇怪的行为有关,人们在JS中不使用它们:

Object.keys({a: undefined}); // ['a']
Object.keys({}); // []

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...