typescript 正在从类型中移除未定义的成员

h4cxqtbf  于 2023-01-21  发布在  TypeScript
关注(0)|答案(1)|浏览(140)

假设我有这样一种类型:

type T = {
    a: number;
    b: undefined;
};

由于b属性的值未定义,我希望能够将{ a: 0 }赋值给此类型的变量,如下所示:

const c: T = { a: 0 };

但这会导致错误Property 'b' is missing in type '{ a: number; }' but required in type 'T'.
是否有办法创建RemoveUndefinedValues泛型,例如:

type T2 = RemoveUndefinedValues<T>; // T2 = { a: number }

Omit<Type, Keys>的工作方式差不多,但是用值代替键?

xam8gpfp

xam8gpfp1#

如果你想删除键,我们有两种方法可以做:要么忽略未定义的键,要么只选择定义的键。
以下是这些工具的实用程序类型:

type DefinedKeys<T> = { [K in keyof T]: T[K] extends undefined ? never : K }[keyof T];

// Can also be written as Exclude<keyof T, DefinedKeys<T>>
type UndefinedKeys<T> = { [K in keyof T]: T[K] extends undefined ? K : never }[keyof T];

然后

type MethodOne = Pick<T, DefinedKeys<T>>;
//   ^? { a: number }
type MethodTwo = Omit<T, UndefinedKeys<T>>;
//   ^? { a: number }

Playground
如果您想使其可选,那么您可以使用上面的两个实用程序通过Map类型的交集来实现这一点:

type MakeUndefinedOptional<T> = ({
    [K in DefinedKeys<T>]: T[K];
} & {
    [K in UndefinedKeys<T>]?: T[K];
}) extends infer O ? { [K in keyof O]: O[K] } : never; // Only for show

type MethodThree = MakeUndefinedOptional<T>;
//   ^? { a: number; b?: undefined }

额外的extends infer O是因为TS不会显示底层的结果类型,这迫使TS“简化”并完全扩展结果。
Playground

相关问题