如何编写将T对象转换为不包括null和undefined的相同对象的类型?



这是我到目前为止所尝试的:


export const purifyObject = <
T extends Record<string, unknown>,
K extends keyof T,
V extends K = T[K] extends null | undefined ? never : K,
P = { [VK in keyof V]: T[VK] },
>(
object: T,
): P => {
const keys = Object.keys(object) as (keyof T)[];
return keys.reduce((pureObject, key) => {
const value = object[key];
if ([null, undefined].includes(value)) return pureObject;
return { ...pureObject, [key]: value };
}, {});
};

TS操场。

const dirtyObject = {
a: 1,
b: null,
c: undefined,
};
console.log(purifyObject(dirtyObject)); // { a: 1 }

我试图得到一个对象,它可以有值空,或未定义,并返回同一对象的类型,不包括键值对值空,和未定义。怎么写呢?

紧跟上面的例子:

{
a: number,
b: null,
c: undefined,
}

应该返回

{ a: number }
{ [key: string]?: string | undefined | null } 

应该返回

{ [key: string]?: string }

{ [key: string]: string }

您可以使用带有as子句的映射类型来排除包含nullundefined的键

type PurifyObject<T> ={ [P in keyof T as T[P] extends null | undefined ? never : P]: T[P] }
export const purifyObject = <
T extends Record<string, unknown>
>(
object: T,
): PurifyObject<T> => {
const keys = Object.keys(object) as (keyof T)[];
return keys.reduce((pureObject, key) => {
const value = object[key] as never;
if ([null, undefined].includes(value)) return pureObject;
return { ...pureObject, [key]: value };
}, {} as PurifyObject<T>);
};

操场上联系

Typescript playground link

首先你需要建立一个包含脏值的键的联合,像这样:

/**
* Build an union of keys which contains dirty value
*/
type DirtyKeys <Object extends Record<string,unknown>> = {
[key in keyof Object]: Object[key] extends null | undefined ? key : never;
}[keyof Object];

然后你可以排除这些键,并使用映射类型来构建一个新的类型,如下所示:

/**
* Map the type to new type excluding dirty keys from `keyof Object` which does not contain null or undefined as value
* Nested Objects are supported too
*/
type Purify<Object extends Record<string,unknown>> = {
[key in Exclude<keyof Object, DirtyKeys<Object>>]: Object[key] extends Record<string,unknown>
? Purify<Object[key]> 
: Object[key]
}

最新更新