typescript - 选择可空属性并使它们不可为空的一般方法
问题描述
让我们有一个以下示例类型:
interface A {
a?: number;
b: string;
}
我的目标是有一种创建以下类型的通用方法:
interface ExpectedA {
a: number;
}
所以我想删除所有不可为空的字段(那些可以包含null
和/或undefined
的)并使那些剩余的可空字段不可为空。
这就是我想象的应该如何工作:
const expA1: ExpectedA = {}; // should NOT pass
const expA2: ExpectedA = {a: 1}; // should pass
const expA3: ExpectedA = {b: ''}; // should NOT pass
const expA4: ExpectedA = {c: 0}; // should NOT pass
const expA5: ExpectedA = {a: 1, b: ''}; // should NOT pass
这是我的非工作尝试(在评论中注释了它的作用和应该做什么):
export type ExtractNullable<T> = {
[K in keyof T]: T[K] extends undefined | null ? NonNullable<T[K]> : never;
};
const a1: ExtractNullable<A> = {}; // should NOT pass, wrong error "prop. b is missing"
const a2: ExtractNullable<A> = {a: 1}; // should pass, wrong - "number not undefined"
const a3: ExtractNullable<A> = {b: ''}; // should NOT pass, wrong - "string not never"
const a4: ExtractNullable<A> = {c: 0}; // should NOT pass, ok - "c not on ..."
const a5: ExtractNullable<A> = {a: 1, b: ''}; // should NOT pass, wrong error "number not undefined, string not never"
我认为问题出在条件类型中,但是查看文档,我不知道要更改什么。
解决方案
您只需要先选择可为空的键,然后再映射它们。
interface A {
a?: number;
b: string;
}
export type NullableKeys<T> = {
[P in keyof T]-? : Extract<T[P], null | undefined> extends never ? never: P
}[keyof T]
export type ExtractNullable<T> = {
[P in NullableKeys<T>]: NonNullable<T[P]>
}
const a1: ExtractNullable<A> = {}; // err
const a2: ExtractNullable<A> = {a: 1}; //ok
const a3: ExtractNullable<A> = {b: ''}; // err
const a4: ExtractNullable<A> = {c: 0}; // err
const a5: ExtractNullable<A> = {a: 1, b: ''}; //err
上述方法适用,strictNullChecks
因为可选属性的类型已更改为 include undefined
。选择可选属性并在没有此编译器选项的情况下工作的版本是:
export type NullableKeys<T> = {
[P in keyof T]-?: Pick<T,P> extends Required<Pick<T, P>> ? never: P
}[keyof T]
推荐阅读
- c# - 无效的密钥哈希。我通过facebook登录游戏时出错
- javascript - Vue.js @click 只注册了一半的时间
- python - 尝试将 tkinter 中的图像正确显示到类的方法中
- go - go rpc 内存泄漏还是不了解?
- ruby - 更新 Ruby Mac OS 10.6.8 Snow Leopard
- javascript - (Javascript) 需要帮助将对象转换为数组
- amazon-web-services - Kinesis 到 S3 自定义分区
- r - 在列表中包含列表
- angularjs - Jasmine - 如何为具有命名属性和对象的数组编写测试
- java - 为什么有时swing JPanel布局会自动调整到最小