使用参考时,Typescript Omit 不显示错误

Posted

技术标签:

【中文标题】使用参考时,Typescript Omit 不显示错误【英文标题】:Typescript Omit does not show error when using reference 【发布时间】:2019-05-16 16:49:19 【问题描述】:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

interface objInterface 
  first: string;
  second: string;


const obj = 
  first: "first",
  second: "second"
;

const out: Omit<objInterface, "first"> = obj;

我原以为这会有一些智能感知错误,但事实并非如此。但是,这确实显示了一些错误,有人知道为什么吗?

const out: Omit<objInterface, "first"> = 
  first: 'first',
  second: 'second'
;

【问题讨论】:

【参考方案1】:

在将对象定义为文字时,TS 仅在多余的属性上出错,这是设计的。 https://www.typescriptlang.org/docs/handbook/interfaces.html#excess-property-checks

【讨论】:

【参考方案2】:

除了@kingdaro 关于对对象字面量进行过多属性检查的正确观点之外,

Omit&lt;T,K&gt; 的定义只是扩大了T 的类型,因此它不包含K 处的已知 属性(“我不知道也不关心K是一个属性;我会忽略它。”),这与 禁止K 的一个属性不同。也就是说,TOmit&lt;T, K&gt; 的子类型,T 类型的任何值也可以分配给Omit&lt;T, K&gt; 类型。如果您的意图实际上是禁止K 的属性,您可以(在某种程度上)通过指定K 属性是可选的并且具有never 的值类型(或undefined,见下文)。让我们称之为ForcefullyOmit&lt;T, K&gt;

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type ForcefullyOmit<T, K extends keyof T> = Omit<T, K> & Partial<Record<K, never>>; 

让我们看看它是否有效:

interface ObjInterface 
  first: string;
  second: string;


const obj = 
  first: "first",
  second: "second"
;

const out: ForcefullyOmit<ObjInterface, "first"> = obj; // error
// types of property "first" are incompatible
// string is not assignable to undefined

看起来不错。

这只是“某种”禁止键,因为它仍然允许该键上的属性为 undefined(或 never),但这是 TypeScript 中的 unresolved issue... 语言并不总是区分缺失的属性和undefined 的属性。

如果您的用例确实需要ForcefullyOmit 的更严格行为,这取决于您。无论如何,希望有所帮助;祝你好运!

【讨论】:

以上是关于使用参考时,Typescript Omit 不显示错误的主要内容,如果未能解决你的问题,请参考以下文章

[TypeScript@2.5] Omit catch error block if not needed

TypeScript 学习笔记 — 基于对象操作的内置类型的使用

为什么TypeScript不能正确返回重写的方法,即使它无法访问?

R dplyr,将 mutate 与 na.omit 一起使用会导致错误大小不兼容 (%d)

为啥`-fno-omit-frame-pointer` 会干扰 ASAN?

Elasticsearch:何时将 omit_norms 选项设置为 false