将T |未定义键转换为键?: t

  • 本文关键字:转换 未定义 typescript
  • 更新时间 :
  • 英文 :


为了提高可读性,我希望一个转换器采用任何类型扩展Record<string,>并且返回一个类型,使不可定义的键成为可选的,显然保留其余的键。

ie:

// I want to turn this
type WithUndefined = {
a: string,
b: number | undefined,
c: boolean | undefined,
};
// Into this
type WithoutUndefined = {
a: string,
b?: number,
c?: boolean,
}

我已经找到了这样做的方法,但是对于我认为很简单的事情来说,它似乎有点复杂。如此之多,甚至VSCode都不能在覆盖层中自行解析类型,使其阅读起来很烦人,完全破坏了目标。

type OnlyKeepsDefined<T extends Record<string, any>> = Pick<
T,
{ [Key in keyof T]: undefined extends T[Key] ? never : Key }[keyof T]
>;
type OnlyKeepsUndefined<T extends Record<string, any>> = Pick<
T,
{ [Key in keyof T]: undefined extends T[Key] ? Key : never }[keyof T]
>;
type RemoveUnionUndefined<T extends Record<string, any>> = {
[Key in keyof T]: undefined extends T[Key] ? Exclude<T[Key], undefined> : T[Key];
};
type UndefinedToOptional<T extends Record<string, any>> = OnlyKeepsDefined<T> &
RemoveUnionUndefined<Partial<OnlyKeepsUndefined<T>>>;
type TestType = {
a: string;
b: number | undefined;
c: undefined;
};
type FilteredTestType = UndefinedToOptional<TestType>;
// Valid
const a: FilteredTestType = { a: "a" }; 
const b: FilteredTestType = { a: "a", b: 1 };
const c: FilteredTestType = { a: "a", b: 1, c: undefined };

有什么好的建议吗?

您可以使用Id类型来解决打印类型,使其平坦:

type Id<T> = {} & {
[P in keyof T]: T[P]
}

操场上联系

对于更简单的版本,我们可以创建一个使用as类过滤键的版本,但是仍然需要可选字段和必选字段的映射之间的交集,所以不确定它是否一定更简单

type UndefinedToOptional<T extends Record<string, any>> = {
// We keep only keys that have undefined in the type and make them optional
[P in keyof T as undefined extends T[P]? P: never]?: T[P]
} &  {
// We keep only keys that do not have undefined in the type
[P in keyof T as undefined extends T[P]? never: P]: T[P]
} 

操场上联系

最新更新