【问题标题】:Typescript Omit does not show error when using reference使用参考时,Typescript Omit 不显示错误
【发布时间】: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'
};

【问题讨论】:

    标签: typescript typescript-types


    【解决方案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 的更严格行为,这取决于您。无论如何,希望有所帮助;祝你好运!

      【讨论】:

        猜你喜欢
        • 2023-02-22
        • 2019-02-16
        • 2017-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多