TypeScript 错误“'删除'运算符的操作数必须是可选的”背后的逻辑是什么?

Aks*_*ain 83 javascript typescript

这是打字稿代码中出现的新错误。

我无法实现其背后的逻辑
文档

/*When using the delete operator in strictNullChecks, 
the operand must now be any, unknown, never, or be optional 
(in that it contains undefined in the type). Otherwise, use of the delete operator is an error.*/

interface Thing {
  prop: string;
}

function f(x: Thing) {
  delete x.prop; // throws error = The operand of a 'delete' operator must be optional.
}
Run Code Online (Sandbox Code Playgroud)

Pac*_*ac0 87

我无法理解其背后的逻辑

我理解的逻辑如下:

接口Thing是一个契约,要求将(非空,非未定义)prop作为string.

如果移除该财产,则合同不再执行。

如果您希望它在删除后仍然有效,只需将其声明为可选?prop?: string

我实际上很惊讶这并没有在早期版本的 TypeScript 中导致错误。

  • 如果您正在使用 React 并希望将 props 传递给组件,但又不想将所有 props 传递给 HTML DOM 元素,因为它们无效,并且您正在使用展开运算符来允许消费者,则这是误报传递所有本机 HTML 属性。然后你复制道具并删除不需要的道具。 (3认同)
  • 圣牛@toni_lehtimaki 这就是我的确切情况......:) (2认同)

Tia*_*ari 64

这背后的逻辑是,您需要使用这样的可选属性来实现您的接口:

interface Thing {
  prop?: string;
}
// OR
interface Thing {
  prop: string | undefined;
}

function f(x: Thing) {
  delete x.prop; 
}
Run Code Online (Sandbox Code Playgroud)

所以接口的契约不会被破坏。


Edg*_*var 28

也许这会有所帮助

const { propToDelete, ...otherProps} = yourObject
return otherProps
Run Code Online (Sandbox Code Playgroud)

这样你就可以使用 otherProps 对象而不会中断


joe*_*dle 27

快速解决

您可以将 的类型更改x为部分:

function f(x: Partial<Thing>) {
  delete x.prop;
}
Run Code Online (Sandbox Code Playgroud)

但我通常不喜欢变异(修改)从可能未知的代码传递给我的对象。所以我通常会创建一个新对象:

function f(x: Thing) {
  const y = { ...x } as Partial<Thing>;
  delete y.prop;
}
Run Code Online (Sandbox Code Playgroud)

由于Partial使所有属性都是可选的,这将允许您从 中删除任何内容y

受到推崇的

更具体地说,您可以使用PartialBy(一个衬垫)或SetOptional(来自 type-fest):

  const y = { ...x } as PartialBy<Thing, 'prop1' | 'prop2'>;
Run Code Online (Sandbox Code Playgroud)

这将使prop1和成为prop2可选的,但保留所有其他属性原样。

笔记

我写下上面的内容const y = value as Type;是因为我觉得这样更容易阅读。但您可能应该使用const y: Type = value;它,因为这样可以更好地进行类型检查


Log*_*ine 9

如果您希望它存在,则可以使用另一个实现:

interface Thing {
  prop: string;
}
interface PropoptionalThing {
  prop?: string;
}

function f(x: Thing): PropoptionalThing {
  let tmp: PropoptionalThing = x;
  delete tmp.prop;
  return tmp;
}
Run Code Online (Sandbox Code Playgroud)


Raj*_*nga 5

prop接口中的属性必须Thing使用?mark标记为可选。

那么你的Thing界面一定是这样的。

interface Thing {
  prop?: string;
}
Run Code Online (Sandbox Code Playgroud)