检查对象 A 中存在的对象 B 的键是否存在于对象 A 中键的另一个数组值中

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

示例代码:

enum ENUM_A { 
  ONE="ONE",
  TWO="TWO",
  THREE="THREE",
  FOUR="FOUR"
}

interface TYPE_A {
  myArray: ENUM_A[],
  mySpecificMapping: {
    [key in ENUM_A]?: boolean
  }
}
const myObject: TYPE_A = {
  myArray: [ENUM_A.ONE, ENUM_A.THREE],
  mySpecificMapping: {
    [ENUM_A.ONE]: true,
    // Uncommenting the line below should result in a TypeScript error
    // [ENUM_A.TWO]: true,
    [ENUM_A.THREE]: true,
    // Uncommenting the line below should result in a TypeScript error
    // [ENUM_A.FOUR]: true,
  }
}

如果“mySpecificMapping”包含“myArray”中不存在的键,则 myObject 应该出错

我想我需要在这里使用自引用类型?

typescript
1个回答
0
投票

是的,要实现此功能,您需要

TypeA
EnumA 中实际存在的
myArray
成员中成为
generic
,如下所示:

interface TypeA<T extends EnumA> {
  myArray: T[],
  mySpecificMapping: {
    [K in T]?: boolean
  }
}

然后您可以注释更改为

const myObject: TypeA<EnumA.ONE | EnumA.THREE> = {
  myArray: [EnumA.ONE, EnumA.THREE],
  mySpecificMapping: {
    [EnumA.ONE]: true,
    [EnumA.THREE]: true
  }
}

如果您将

[EnumA.TWO]: true
添加到
mySpecificMapping
,则会出现错误。但写出
EnumA.ONE | EnumA.THREE
类型的参数是乏味且多余的。如果 TypeScript 能够为您推断该类型参数,那就太好了,但这是 microsoft/TypeScript#32794 所请求的缺失功能。

如果你想要泛型类型参数推断,你需要创建一个泛型function来配合

TypeA
。这是一个用于此目的的辅助函数:

const typeA = <T extends EnumA>(t: TypeA<T>) => t;

const myObject = typeA({
  myArray: [EnumA.ONE, EnumA.THREE],
  mySpecificMapping: {
    [EnumA.ONE]: true,
    [EnumA.THREE]: true,
  }
});

现在您将看到

myObject
被推断为类型
TypeA<EnumA.ONE | EnumA.THREE>
,而无需您自己写出来。写
const myObject = typeA({⋯})
而不是
const myObject: TypeA = {⋯}
的工作量和击键次数大约相同,所以希望这是可以接受的。


无论如何,让我们确保您得到您所要求的行为:

const myObject = typeA({
  myArray: [EnumA.ONE, EnumA.THREE],
  mySpecificMapping: {
    [EnumA.ONE]: true,    
    [EnumA.TWO]: true, // error! 
    [EnumA.THREE]: true,
  }
});

看起来不错。当您添加

mySpecificMapping
中不存在的
myArray
键时,您会收到错误消息。

Playground 代码链接

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