使用可选链接运算符时,类型上不存在属性“x”

jac*_*118 7 typescript typescript-generics typescript-typings

我想在打字稿中使用可选链接运算符,但出现错误Property 'dog' does not exist on type '{ name: string; cat: Record<string, string>; }'. 。打字稿的错误抱怨完全有道理,但我想知道我是否可以四处走动? 操场

const adventurer: {name: string;cat:Record<string, string>} = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer?.dog;
console.log(dogName);

Run Code Online (Sandbox Code Playgroud)

Tax*_*xel 5

为什么会出现这种情况?

您通过为冒险家提供一个类型来告诉 TS 编译器,该类型永远adventurer不会有属性(编辑:感谢 @jcalz 指出这并不完全正确。请查看下面的评论以获取更多信息)。解决这个问题有两种主要方法:dog

通过断言另一种类型(就像任何类型)告诉 TypeScript 你更了解

const dogName = (adventurer as any)?.dog;
console.log(dogName);
Run Code Online (Sandbox Code Playgroud)

更改冒险家的类型以选择性地包括dog

const adventurer: {name: string;cat:Record<string, string>; dog?: string} = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer?.dog;
console.log(dogName);
Run Code Online (Sandbox Code Playgroud)

  • “‘冒险家’**永远不会**拥有属性‘狗’”...这并不完全正确,因为 TypeScript 有[结构子类型](https://www.typescriptlang.org/docs/handbook/typescript- in-5-minutes-func.html#structural-typing),请参阅[此处](https://tsplay.dev/mAV9QW)。有[多余的属性检查](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-6.html#stricter-object-literal-assignment-checks),这使得它不太可能意外地直接以这种方式注释对象文字,但它更多的是一个 linter 规则,而不是类型系统约束。 (3认同)