繁体   English   中英

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

[英]TS2339: Property 'X' does not exist on type 'Y' (Non-indexable type union case)

与类似问题的区别

错误 TS2339 中:属性 'x' 在类型 'Y' 上不存在,主题是可索引类型 这不是,所以很可能需要其他解决方案。

问题

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":不能写如)。

在此处输入图片说明

defaultValue相同的歌曲( isUndefined ):

在此处输入图片说明

您的代码与discriminated union非常相似,但您为此使用了required

JavaScript(和 TypeScript)区分具有undefined值的现有属性和不存在的属性。 因此,要使您的代码正常工作,您应该向所有接口添加可选属性requireddefaultValue

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

以下代码将起作用

function f1(targetPropertySepcification: NumberPropertySpecification) {
  if (targetPropertySepcification.required === true) {
    // targetPropertySepcification is of type INumberPropertySpecification__Required
    const n: number | undefined = targetPropertySepcification.invalidValueSubstitution;
  } else if (targetPropertySepcification.required === false) {
    // targetPropertySepcification is of type INumberPropertySpecification__Optional
  } else if (targetPropertySepcification.required === undefined) {
    // targetPropertySepcification is of type INumberPropertySpecification__HasDefault
    const n: number = targetPropertySepcification.defaultValue;
  }

  if (targetPropertySepcification.defaultValue === undefined) {
    // Here targetPropertySepcification is of type INumberPropertySpecification__Required | INumberPropertySpecification__Optional 
    //  and required property is of type true | false, or simply boolean
    const rt: boolean = targetPropertySepcification.required
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM