使用引用时 Typescript Omit 不显示错误

Typescript Omit does not show error when using reference

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'
};

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

除了@kingdaro关于过度属性检查对象文字的正确观点外,

Omit<T,K> 的定义只是扩大了 T 的类型,因此它不包含 known 属性 at [=14] =] ("I don't know or care if K is a property; I will ignore it."),这与 禁止 属性 at K 不同。也就是说,TOmit<T, K> 的子类型,任何类型 T 的值也可以分配给类型 Omit<T, K>。如果您的意图实际上是 禁止 K 的 属性,您可以(有点)通过指定 K [=51] 来做到这一点=] 是可选的,值类型为 never(或 undefined,见下文)。我们称之为 ForcefullyOmit<T, K>:

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

看起来不错。

它只是 "kind of" 禁止键,因为它仍然允许在 undefined(或 never)类型的键上使用 属性,但这有点像TypeScript 中的 unresolved issue...该语言并不总是区分缺失属性和 undefined 属性。

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