TypeScript 错误“'delete' 运算符的操作数必须是可选的”背后的逻辑是啥?

Posted

技术标签:

【中文标题】TypeScript 错误“\'delete\' 运算符的操作数必须是可选的”背后的逻辑是啥?【英文标题】:What is the logic behind the TypeScript error "The operand of a 'delete' operator must be optional"?TypeScript 错误“'delete' 运算符的操作数必须是可选的”背后的逻辑是什么? 【发布时间】:2020-12-21 10:01:39 【问题描述】:

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

我无法实现它背后的逻辑Documentation

/*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.

【问题讨论】:

你的问题包括答案...When using the delete operator in strictNullChecks, the operand must now be any, unknown, never, or be optional 【参考方案1】:

我无法理解其背后的逻辑

我理解的逻辑如下:

接口Thing 是要求将(非空,非未定义)prop 作为string 的合约。

如果一个人删除了财产,那么合同就不再执行了。

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

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

【讨论】:

如果您使用 React 并希望将 props 传递给组件,但不想将所有 props 传递给 html DOM 元素,因为它们无效并且您正在使用扩展运算符来允许消费者传递所有原生 HTML 属性。然后你复制道具并删除不必要的道具。 圣牛@toni_lehtimaki 那是我的确切情况...... :) 在原型链仍然包含属性的情况下也是误报 - 因为delete 语句仅适用于直接属性,而不适用于继承的属性。例如,您可以在 Element 上执行 delete node.getAttribute ,一切都很好 - 您可能已经删除了隐藏继承属性的属性,但它仍然从原型继承 getAttribute @aProgger 乍一看,我会说一些“干净”的方法是有两种类型,一种包含所有数据,另一种是“轻量级”版本。不过,可能值得自己提出更多细节的问题。 @Pac0 有同样的想法并且已经实现了。我创建了一个(超)类函数,它收集所有数据并将它们作为新类型返回。【参考方案2】:

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

interface Thing 
  prop?: string;

// OR
interface Thing 
  prop: string | undefined;


function f(x: Thing) 
  delete x.prop; 

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

【讨论】:

【参考方案3】:

如果您希望它存在,则另一种实现:

interface Thing 
  prop: string;

interface PropoptionalThing 
  prop?: string;


function f(x: Thing): PropoptionalThing 
  let tmp: PropoptionalThing = x;
  delete tmp.prop;
  return tmp;

【讨论】:

【参考方案4】:

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

function f(x: Partial<Thing>) 
  delete x.prop;

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

function f(x: Thing) 
  const y =  ...x  as Partial<Thing>;
  delete y.prop;

由于Partial 将所有属性设为可选,这将允许您从y 中删除任何内容。

如果您想更具体,可以使用SetOptional from typesfest:

  const y =  ...x  as SetOptional<Thing, 'prop1' | 'prop2'>;

这将使prop1prop2 成为可选,但保持所有其他属性为强制性(必需)。

【讨论】:

【参考方案5】:

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

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

interface Thing 
  prop?: string;

【讨论】:

以上是关于TypeScript 错误“'delete' 运算符的操作数必须是可选的”背后的逻辑是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在析构函数中调用“delete”运算符时出现编译器错误“编译器堆空间不足”

new和delete运算符 c/c++

C++ 中的 delete vs delete[] 运算符

C++ new和delete运算符

C++ new和delete运算符简介

重载类的new和delete运算符成员函数