adm*_*r86 1 reflection typescript
有没有一种方法可以获取打字稿界面或对象的所有必需属性。类似Object.getOwnPropertyDescriptors(myObject)或keyof T带有信息属性的东西是必需的/可选的
Gab*_*ani 11
如果 2022 年有人仍在寻找答案,这对我有用:
export type GetOptionalKeys<T> = {[K in keyof T as (undefined extends T[K] ? K : never)]: T[K]}
export type GetRequiredKeys<T> = {[K in keyof T as (undefined extends T[K] ? never : K)]: T[K]}
Run Code Online (Sandbox Code Playgroud)
资源:https ://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as
在运行时这是不可能的,因为属性的必要性/可选性仅存在于TypeScript类型系统中,而在代码实际运行时已被擦除。您可以通过装饰器等添加自己的运行时信息,但是为此,您需要修改生成类和对象的实际代码。因此,不可能获得给定对象或构造函数的必需属性名称的数组。
在设计时它是可能提取的类型的所需的/可选的键,作为的一个亚型keyof T。该解决方案依赖于条件类型和以下事实:空对象类型{}被认为可分配给弱类型(没有必需属性的类型)。像这样:
type RequiredKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? never : K }[keyof T];
type OptionalKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never }[keyof T];
Run Code Online (Sandbox Code Playgroud)
以及示例用法:
interface SomeType {
required: string;
optional?: number;
requiredButPossiblyUndefined: boolean | undefined;
}
type SomeTypeRequiredKeys = RequiredKeys<SomeType>;
// type SomeTypeRequiredKeys = "required" | "requiredButPossiblyUndefined"
type SomeTypeOptionalKeys = OptionalKeys<SomeType>;
// type SomeTypeOptionalKeys = "optional"
Run Code Online (Sandbox Code Playgroud)
带有索引签名的类型不能很好地发挥作用:
interface SomeType {
required: string;
optional?: number;
requiredButPossiblyUndefined: boolean | undefined;
[k: string]: unknown; // index signature
}
type SomeTypeRequiredKeys = RequiredKeys<SomeType>;
// type SomeTypeRequiredKeys = never
type SomeTypeOptionalKeys = OptionalKeys<SomeType>;
// type SomeTypeOptionalKeys = string
Run Code Online (Sandbox Code Playgroud)
不知道您的用例是否关心可索引类型。如果是这样,那么存在一种更复杂的解决方案,该解决方案通过首先提取已知文字键然后检查是否需要/可选来解决该问题:
type RequiredLiteralKeys<T> = { [K in keyof T]-?:
string extends K ? never : number extends K ? never : {} extends Pick<T, K> ? never : K
} extends { [_ in keyof T]-?: infer U } ? U extends keyof T ? U : never : never;
type OptionalLiteralKeys<T> = { [K in keyof T]-?:
string extends K ? never : number extends K ? never : {} extends Pick<T, K> ? K : never
} extends { [_ in keyof T]-?: infer U } ? U extends keyof T ? U : never : never;
type IndexKeys<T> = string extends keyof T ? string : number extends keyof T ? number : never;
Run Code Online (Sandbox Code Playgroud)
结果是:
type SomeTypeRequiredKeys = RequiredLiteralKeys<SomeType>;
// type SomeTypeRequiredKeys = "required" | "requiredButPossiblyUndefined"
type SomeTypeOptionalKeys = OptionalLiteralKeys<SomeType>;
// type SomeTypeOptionalKeys = "optional"
type SomeTypeIndexKeys = IndexKeys<SomeType>;
// type SomeTypeIndexKeys = string
Run Code Online (Sandbox Code Playgroud)
希望能有所帮助。祝好运!
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |