类型联合不检查多余的属性 [英] Type union not checking for excess properties

查看:24
本文介绍了类型联合不检查多余的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设有一个对象,它具有属性 ABC,例如:

const temp = {答:1、乙:2,}

const temp = {丙:3,}

直觉上我认为这种类型是:

type T = {A: number, B: number} |{C:数字};const 有效:T = {A: 1, B: 2};const 也有效:T = {C: 3};//应该抱怨但它没有const 无效:T = {A: 1, B: 2, C: 3};//也应该抱怨const 也无效:T = {A:1, C: 3};

但是 TS 将这种类型视为 {A?: number, B?: number, C?: number} 并且基本上 | 使字段可选但我希望 TS当我将 C 属性添加到 AB

时抱怨类型不一致

如何归档所需的类型?

解决方案

在联合如何与多余的属性检查结合工作方面,这有点奇怪.{A:1, C: 3} 实际上与 {C: number} 兼容,除了额外的属性检查:

const o = {A:1, C: 3};const ok: {C: number} = o;//没有直接的文字赋值,没有多余的属性检查const nok: {C: number} = { A:1, C: 3};//多余的属性检查开始

游乐场链接

如果工会有很多成员,您也可以使用 此处 中的 StrictUnion

<预><代码>类型 UnionKeys<T>= T 扩展 T ?keyof T : 从不;输入 StrictUnionHelper;= T 扩展任何 ?与Partial<Record<Exclude<UnionKeys<TAll>,keyof T>,从不>>: 绝不;输入 StrictUnion= StrictUnionHelpertype T = StrictUnion<{A: number, B: number} |{C:数字}>;const 有效:T = {A: 1, B: 2};const 也有效:T = {C: 3};//错误const 无效:T = {A: 1, B: 2, C: 3};//错误const 也无效:T = {A:1, C: 3};

游乐场链接

let's imagine a have an object that either have properties A and B or C, e.g.:

const temp = {
  A: 1,
  B: 2,
}

or

const temp = {
  C: 3,
}

And intuitively I see this type as:

type T =  {A: number, B: number} | {C: number};

const valid: T = {A: 1, B: 2};
const alsoValid: T = {C: 3};

// Should complain but it does not
const invalid: T  = {A: 1, B: 2, C: 3};
// Also should complain
const alsoInvalid: T = {A:1, C: 3};

But TS treats such type as {A?: number, B?: number, C?: number} and basically | makes fields optional but I want TS to complain about inconsistent type when I add C property to A and B


How can I archive the desirable type?

解决方案

This is a bit of a quirk in how unions work in conjunction with excess property checks. {A:1, C: 3} is actually compatible with {C: number} except for excess property checks:

const o = {A:1, C: 3};
const ok: {C: number} = o; // No direct literal assignment, no excess property checks
const nok: {C: number} = { A:1, C: 3}; // Excess property checks kick in 

Playground Link

And the quirk of excess property checks is that for unions, it allows any property from any union constituent to be present in the assigned object literal.

You can get an error if the union constituents are incompatible one with another:

type T =  {A: number, B: number} | {C: number, A?: undefined, B?: undefined };

const valid: T = {A: 1, B: 2};
const alsoValid: T = {C: 3};

// Error
const invalid: T  = {A: 1, B: 2, C: 3};
//Error
const alsoInvalid: T = {A:1, C: 3};

Playground Link

You can also use the StrictUnion from here if the union has a lot of memebers


type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>

type T =  StrictUnion<{A: number, B: number} | {C: number }>;

const valid: T = {A: 1, B: 2};
const alsoValid: T = {C: 3};

// Error
const invalid: T  = {A: 1, B: 2, C: 3};
//Error
const alsoInvalid: T = {A:1, C: 3};

Playground Link

这篇关于类型联合不检查多余的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆