pol*_*oli 5 types strong-typing typescript
假设我有一些 enum E { A = "a", B = "b"}。我想强制某些接口或类型(为了可读性,我只提到接口)具有 E 的所有键。但是,我想分别指定每个字段的类型。因此, { [P in E]: any }甚至{ [P in E]: T }都不是正确的解决方案。
例如,代码可能包含两个实现 E 的接口:
E { A = "a", B = "b"}Interface ISomething { a: string, b: number}Interface ISomethingElse { a: boolean, b: string}随着 E 在开发过程中的扩展,它可能会变成:
E { A = "a", B = "b", C="c"}Interface ISomething { a: string, b: number, c: OtherType}Interface ISomethingElse { a: boolean, b: string, c: DiffferntType}几个小时后:
E { A = "a", C="c", D="d"}Interface ISomething { a: string, c: ChosenType, d: CarefullyChosenType}Interface ISomethingElse { a: boolean, c: DiffferntType, d: VeryDifferentType}等等等等。因此,从https://www.typescriptlang.org/docs/handbook/advanced-types.html看来,它还不受支持。有没有我遗漏的打字稿黑客?
jca*_*alz 11
我猜你已经致力于写出 theenum和 the interface,然后希望 TypeScript 会警告你interface缺少的键enum(或者如果它有额外的键)?
假设你有
enum E { A = "a", B = "b", C="c"};
interface ISomething { a: string, b: number, c: OtherType};
Run Code Online (Sandbox Code Playgroud)
您可以使用条件类型让 TypeScript 找出E的键中是否缺少 的任何成分ISomething:
type KeysMissingFromISomething = Exclude<E, keyof ISomething>;
Run Code Online (Sandbox Code Playgroud)
never如果您没有缺少任何密钥,则应该是这种类型ISomething。否则,它将是Elike的值之一E.C。
您还可以让编译器弄清楚是否ISomething有任何不是组成部分的键E,也可以使用条件类型......尽管这更复杂,因为您无法enum以预期的方式以编程方式操作s。这里是:
type ExtraKeysInISomething = {
[K in keyof ISomething]: Extract<E, K> extends never ? K : never
}[keyof ISomething];
Run Code Online (Sandbox Code Playgroud)
同样,never如果你没有额外的钥匙,这将是。然后,您可以never通过使用泛型约束和默认类型参数来强制编译时错误,如果其中之一不是:
type VerifyISomething<
Missing extends never = KeysMissingFromISomething,
Extra extends never = ExtraKeysInISomething
> = 0;
Run Code Online (Sandbox Code Playgroud)
类型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; // no error
Run Code Online (Sandbox Code Playgroud)
和
enum E { A = "a", B = "b", C = "c" }
interface ISomething { a: string, b: number } // oops, missing c
type VerifyISomething<
Missing extends never = KeysMissingFromISomething, // error!
Extra extends never = ExtraKeysInISomething
> = 0; // E.C does not satisfy the constraint
Run Code Online (Sandbox Code Playgroud)
和
enum E { A = "a", B = "b", C = "c" }
interface ISomething { a: string, b: number, c: OtherType, d: 1} // oops, extra d
type VerifyISomething<
Missing extends never = KeysMissingFromISomething,
Extra extends never = ExtraKeysInISomething // error!
> = 0; // type 'd' does not satisfy the constraint
Run Code Online (Sandbox Code Playgroud)
所以所有这些都有效......但它并不漂亮。
一种不同的hacky方法是使用一个dummy,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 {}
Run Code Online (Sandbox Code Playgroud)
如果您遗漏了其中一个属性,则会出现错误:
class CSomething implements Record<E, unknown> { // error!
a!: string;
b!: number;
}
// Class 'CSomething' incorrectly implements interface 'Record<E, unknown>'.
// Property 'c' is missing in type 'CSomething'.
Run Code Online (Sandbox Code Playgroud)
它不会警告您有关额外属性的信息,尽管您可能不在乎?
无论如何,希望其中之一对您有用。祝你好运。
| 归档时间: |
|
| 查看次数: |
5620 次 |
| 最近记录: |