如果存在一项属性,请确保存在其他属性

问题描述 投票:0回答:1

我想构建一个需要存在某些属性的类型,以防存在另一个属性。

为此,我想到使用联合类型的交集。联合类型可以是某些属性及其要求的组合,也可以是空类型。

以下代码不起作用,因为尽管缺少

desc
属性,但它不会出错:

export type A = {
  a: string;
  desc: string;
};

export type B = {
  b: string;
} & (A | {});

const v: B = {
  b: "",
  a: "123"
};

{}
替换
Record<string, never>
会导致错误,因为所有属性现在都是
never
类型。

export type A = {
  a: string;
  desc: string;
};

export type B = {
  b: string;
} & (A | Record<string, never>);

const v: B = {
  b: "",
  a: "123"
};

有没有办法让这个概念发挥作用?或者也许有更好的方法?

typescript union-types intersection-types
1个回答
0
投票

您的方法在概念上是正确的 - 您想要

A
的并集和与 A 没有公共键的类型。

不幸的是,类似于

(A | {})
的东西不起作用 - TS 类型允许额外的属性。

TS 对对象文字进行了过多的属性检查,但它不起作用

{}
联合。

const foo: {} = {a: 1}

ts-eslint 甚至有一条禁止其使用的规则:

Don't use `{}` as a type. `{}` actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want `Record<string, unknown>` instead.
- If you want a type meaning "any value", you probably want `unknown` instead.
- If you want a type meaning "empty object", you probably want `Record<string, never>` 

A | Record<string, never>
单独工作效果很好,但是,正如您所注意到的,它不能作为与
{b: string;}
相交的一部分 - 记录力
b
永远不会。

您可以使用以下类型来表达

A or sth having no keys of A

export type A = {
  a: string;
  desc: string;
};

type NoneOf<T> = {
    [K in keyof T]?: never
}

export type B = {
  b: string;
} & (A | NoneOf<A>);

const v: B = {
  b: "",
  a: "123"
};

Exact Types #12936的相关请求 - 不幸的是多年来没有实施。

© www.soinside.com 2019 - 2024. All rights reserved.