TS2339:类型“ Y”上不存在属性“ X”(不可索引类型的联合用例)

时间:2019-12-02 03:29:53

标签: typescript typescript-typings

与类似问题的区别

error TS2339: Property 'x' does not exist on type 'Y'中,主题为indexable type。这里不是,所以很可能需要其他解决方案。

问题

interface INumberPropertySpecification__CommonParameters {
  readonly type: PROPERTIES_TYPES.NUMBER; // enum
  readonly numberType: NUMBER_TYPES; // enum
}

export type NumberPropertySpecification =
      INumberPropertySpecification__Required |
      INumberPropertySpecification__HasDefault |
      INumberPropertySpecification__Optional;

在上面的代码中,键入NumberPropertySpecification是以下情况的联合:

  1. 该属性是必需的。在这种情况下,库用户必须理解它,因此我让他明确指定required: true
interface INumberPropertySpecification__Required extends INumberPropertySpecification__CommonParameters {
    readonly required: true;
    readonly invalidValueSubstitution?: number;
}

// Example:

const requiredNumberPropertySpecification: INumberPropertySpecification__Required = {
  type: PROPERTIES_TYPES.NUMBER,
  numberType: NUMBER_TYPES.ANY_REAL_NUMBER,
  required: true // user MUST comprehend it, so I make him to explicitly specify it
}
  1. 该属性具有默认值;这意味着它不是必需的。我不想让用户指定required: false,因为很明显。
interface INumberPropertySpecification__HasDefault extends INumberPropertySpecification__CommonParameters {
    readonly defaultValue: number;
}

// Example
const requiredNumberPropertySpecification: INumberPropertySpecification__HasDefault = {
  type: PROPERTIES_TYPES.NUMBER,
  numberType: NUMBER_TYPES.ANY_REAL_NUMBER,
  default: 1
}
  1. 该属性是可选的。在这种情况下,用户必须理解它,因此我让他明确指定required: false
interface INumberPropertySpecification__Optional extends INumberPropertySpecification__CommonParameters {
    readonly required: false;
}

// Example:

const requiredNumberPropertySpecification: INumberPropertySpecification__Optional = {
  type: PROPERTIES_TYPES.NUMBER,
  numberType: NUMBER_TYPES.ANY_REAL_NUMBER,
  required: false // user MUST comprehend it, so I make him to explicitly specify it
}

错误

我们无法检查targetPropertySpecification.required === true。在这种情况下,TypeScript类型检查算法会产生过大的杀伤力,因为在未定义targetPropertySpecification.required时,不会发生JavaScript错误(即使只是if(targetPropertySpecification.required),但使用"@typescript-eslint/strict-boolean-expressions":的人也不能这样写)

enter image description here

defaultValueisUndefined)相同的歌曲:

enter image description here

1 个答案:

答案 0 :(得分:1)

您的代码与discriminated union非常相似,但是您为此使用了class LoginActivity : AppCompatActivity(), OnCompleteListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) } // onComplete Task here how it is possible }

JavaScript(和TypeScript)区分具有required值的现有属性和不存在的属性。因此,为使代码正常工作,应在所有接口中添加可选属性undefinedrequired

defaultValue

interface INumberPropertySpecification__Required extends INumberPropertySpecification__CommonParameters { readonly required: true; readonly invalidValueSubstitution?: number; readonly defaultValue?: undefined; } 的类型显式为defaultValue,并且设置为可选。

对其他两个接口也应进行类似的修改。

undefined

现在您仍然可以做

interface INumberPropertySpecification__HasDefault extends INumberPropertySpecification__CommonParameters {
  readonly defaultValue: number;
  readonly required?: undefined;
}

interface INumberPropertySpecification__Optional extends INumberPropertySpecification__CommonParameters {
  readonly required: false;
  readonly defaultValue?: undefined;
}

您不需要为const targetPropertySepcification: NumberPropertySpecification = { required: true, type: PROPERTIES_TYPES.NUMBER, numberType: NUMBER_TYPES.T1 } 提供价值。设置为defaultValue

以下代码将起作用

undefined