我猜你想要写出enum
和interface
,希望TypeScript会警告你interface
中缺少了enum
的键(或者如果它有额外的键)?
假设你有以下代码:
enum E { A = "a", B = "b", C="c"};
interface ISomething { a: string, b: number, c: OtherType};
你可以使用
条件类型来让 TypeScript 判断
E
中是否有任何成员缺失于
ISomething
的键中:
type KeysMissingFromISomething = Exclude<E, keyof ISomething>
如果你的 ISomething
中没有任何缺失的键,那么这种类型应该是 never
。否则,它将成为 E
的值之一,例如 E.C
。
您还可以使用条件类型让编译器找出 ISomething
是否有任何不属于 E
的键...尽管这更复杂,因为无法以预期的方式对枚举进行编程操作。代码如下:
type ExtraKeysInISomething = {
[K in keyof ISomething]: Extract<E, K> extends never ? K : never
}[keyof ISomething];
如果你没有额外的键,这将永远不会发生。然后,你可以使用泛型约束和默认类型参数来强制在这两种情况下都是never
时出现编译时错误:
type VerifyISomething<
Missing extends never = KeysMissingFromISomething,
Extra extends never = ExtraKeysInISomething
> = 0
VerifyISomething
这个类型本身并不重要(它始终是 0
),但是通用参数 Missing
和 Extra
,如果它们各自的默认值不是 never
,将会给您带来错误。
让我们试一试:
enum E { A = "a", B = "b", C = "c" }
interface ISomething { a: string, b: number, c: OtherType }
type VerifyISomething<
Missing extends never = KeysMissingFromISomething,
Extra extends never = ExtraKeysInISomething
> = 0;
and
enum E { A = "a", B = "b", C = "c" }
interface ISomething { a: string, b: number }
type VerifyISomething<
Missing extends never = KeysMissingFromISomething,
Extra extends never = ExtraKeysInISomething
> = 0;
和
enum E { A = "a", B = "b", C = "c" }
interface ISomething { a: string, b: number, c: OtherType, d: 1}
type VerifyISomething<
Missing extends never = KeysMissingFromISomething,
Extra extends never = ExtraKeysInISomething
> = 0;
所以所有的东西都能运行... 但看起来并不美观。
另一个权宜之计是使用一个虚拟的class
,其唯一目的是在您未添加正确属性时责骂您:
enum E { A = "a", B = "b" , C = "c"};
class CSomething implements Record<E, unknown> {
a!: string;
b!: number;
c!: boolean;
}
interface ISomething extends CSomething {}
如果您忽略其中一个属性,将会出现错误:
class CSomething implements Record<E, unknown> {
a!: string;
b!: number;
}
尽管可能你并不在意,但它不会警告你关于额外的属性。
总之,希望其中之一适合你。祝好运!
class
定义可以使用implements
。 因此,interface ISomething implements Record<E, unknonwn> { ... }
是一个错误。 您可以使用extends
,例如interface ISomething extends Record<E, unknown> {}
,但这不再警告您缺少的属性...ISomething
已经具有来自E
的键和类型为unknown
的属性。 - jcalzexport type MatchesKeysOfEnum<T, Enum> = ???
- Jamesconst myObject = {} satisfies Record<MyEnum, string>
。 - James