简体   繁体   English

TypeScript 如何强制执行多种类型选项,类型“Y”上不存在属性“X”

[英]TypeScript how to enforce a type of multiple type options, Property 'X' does not exist on type 'Y'

In a data structure which is just an object, the keys are strings and the values can be another object or false ( {} or false ), iterating through the values of the data structure and checking if it's an object and then mutating the nested data structure, it still errors, I assume because it could be a boolean - Property 'X' does not exist on type 'boolean | Y'.在一个只有 object 的数据结构中,键是字符串,值可以是另一个 object 或 false( {}false ),遍历数据结构的值并检查它是否是 object,然后改变嵌套数据结构,它仍然是错误的,我假设是因为它可能是 boolean - Property 'X' does not exist on type 'boolean | Y'. Property 'X' does not exist on type 'boolean | Y'. What is the best way to fix this?解决此问题的最佳方法是什么? Example below:下面的例子:

type Definition = {
  [key: string]: string;
};

type Dictionary = {
  [word: string]: Definition | boolean;
};

function checkWorkds(words: Dictionary) {
  for (let [key, val] of Object.entries(words)) {
    if (val !== false) {
      val['etymology'] = "idk"; // <--- Error here :sob:
    }
  }
}

const dict: Dictionary = {
  hello: {
    name: "hello",
    language: "english"
  },
  bob: false,
  hola: {
    name: "hola",
    language: "spanish"
  }
};

checkWorkds(dict);

The exact error in the example above is上面例子中的确切错误是

Property 'etymology' does not exist on type 'true | Definition'.
  Property 'etymology' does not exist on type 'true'.

It seems that if (typeof val !== 'boolean') { seems to work, however I was curious if there is an alternative/The Right Way as this is a trivial example and in the production code we have lots of nested values that can either be other objects or false .似乎if (typeof val !== 'boolean') {似乎有效,但是我很好奇是否有替代方法/正确的方法,因为这是一个简单的示例,并且在生产代码中我们有很多嵌套值可以是其他对象或false

boolean type has true and false . boolean类型有truefalse Checking whether val !== false isn't enough;检查val !== false是否还不够; only false is eliminated, so there is still Definition | true只有false被剔除,所以还有Definition | true Definition | true left. Definition | true左。 You'll need to...你需要...

either (1) adjust Dictionary type to have only false value if you only use this Boolean value (1) 如果您只使用此 Boolean 值,则将Dictionary类型调整为只有false

type Dictionary = {
  [word: string]: Definition | false;
};

or (2) check val !== false && val !== true or typeof val !== 'boolean' so that there are no more boolean possibilities left in the union.或 (2) 检查val !== false && val !== truetypeof val !== 'boolean'以便联合中不再有boolean可能性。

function checkWorkds(words: Dictionary) {
  for (let [key, val] of Object.entries(words)) {
    if (typeof val !== 'boolean') {
      val['etymology'] = "idk"; // <--- no more error
    }
  }
}

Instead of val !== false , you should be comparing the type using typeof , this way typesript will know for sure that within the if clause has nothing to do with boolean您应该使用typeof比较type ,而不是val !== false ,这样 typesript 就会确定在if子句中与boolean

Playground 操场

For checking the exact type you want to have, use an equal operator so you won't have any issue if you add more types to Dictionary in the future.要检查您想要的确切类型,请使用等于运算符,这样如果您将来向Dictionary添加更多类型,就不会有任何问题。

function checkWorkds(words: Dictionary) {
  for (let [key, val] of Object.entries(words)) {
    if (typeof val === 'object') { // <--- Instead of typeof val !== 'boolean'
      val['etymology'] = "idk";
    }
  }
}

Ex: Checking type if !== you will be having type error if adding string to the union:例如:检查类型 if !==如果将string添加到联合中,您将遇到类型错误:

type Dictionary = {
  [word: string]: Definition | boolean | string;
};

在此处输入图像描述

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

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