【问题标题】:Create a type that allow one member within an interface创建一个允许接口中的一个成员的类型
【发布时间】:2021-03-08 10:38:19
【问题描述】:

我正在使用 Typescript 3.9.x

假设我有一个接口:

interface mytype {
    foo: Foo
    bar: Bar
    baz: Baz
}

我想实现一个OnlyOneOfType<T> 类型,它只允许接口中的一个成员。

这样:

const test1: OnlyOneOfType<mytype> = {foo: 'FOO'}; // PASSES
const test2: OnlyOneOfType<mytype> = {bar: 'BAR'}; // PASSES

const test3: OnlyOneOfType<mytype> = {foo: 'FOO', bar: 'BAR'}; // fails

【问题讨论】:

  • 你的问题我不清楚。您在寻找Set 吗?
  • 我可以为您提供一个简单的解决方案,它可以处理您的示例案例,但也可以接受不需要的属性为 undefined 的对象,例如{foo: 'FOO', bar: undefined}。拒绝这些将更加困难。
  • @Oblosys 我更喜欢未定义属性被拒绝但我也希望看到简单的解决方案。
  • @Terry,请注意,要求 OnyOneOfType&lt;mytype &gt;{foo: Foo} | {bar: Bar} | {baz: Baz} 与要求它只允许一个成员(参见 this q/a)不同。你想要哪一个?前者直截了当;后者不那么重要,但仍然合理。两者都将允许{foo: "FOO", bar: undefined}。 TypeScript 中没有特定类型允许{foo: "FOO"} 并拒绝{foo: "FOO", bar: undefined}。您可以使用泛型更接近,但我怀疑这是否值得。
  • @Oblosys 嘿,不,我猜你是对的。我想早点拥有K in keyof T 足以在以后保持P in K 的同态性(这不是一个词)。我没有意识到这一点。 (在联合中包含undefined,即使它不是同态的也会发生)

标签: typescript typescript-generics


【解决方案1】:

你是指这种类型吗?

type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> &
    {
        [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>>;
    }[Keys];

type OnlyOneOfType<T> = RequireOnlyOne<T, keyof T>

interface mytype {
    foo: 'FOO'
    bar: 'BAR'
    baz: 'BAZ'
}

const test1: OnlyOneOfType<mytype> = { foo: 'FOO' }; // PASSES
const test2: OnlyOneOfType<mytype> = { bar: 'BAR' }; // PASSES
const test3: OnlyOneOfType<mytype> = { foo: 'FOO', bar: 'BAR' }; // FAILS

这与 KPD 在此问题中的回答相同...url

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    相关资源
    最近更新 更多