typescript 如何编写一个类型,将T对象转换为除null和undefined之外的相同对象?

oknrviil  于 2023-01-14  发布在  TypeScript
关注(0)|答案(2)|浏览(145)

这是我目前所尝试的:

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 };
  }, {});
};

TSPlayground。

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

我试图得到一个对象,它的值可以是null,或者是undefined,并且返回相同对象的类型,除了值为null,或者是undefined的键-值对。
遵循上述示例:

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

应该返回
一个三个三个一个
应该返回

{ [key: string]?: string }

{ [key: string]: string }
5kgi1eie

5kgi1eie1#

可以将Map类型与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>);
};

Playground链接

368yc8dk

368yc8dk2#

typescript Playground链接
首先,你需要构建一个包含脏值的键的并集,如下所示:

/**
 * 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的类型构建一个新类型,如下所示:

/**
 * 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]
}

相关问题