键入从对象中删除密钥

时间:2019-01-15 13:14:37

标签: typescript

我想设置一个使用代码从对象中删除键的函数:

type GenericObject = {
  [key: string]: any;
};

const removeKey = (
  inputObject: GenericObject,
  key: string,
) => {
  if (!inputObject.hasOwnProperty(key)) {
    return inputObject;
  }

  const {
    [key]: _,
    ...rest
  } = inputObject;

  return rest;
};

这在一定程度上可行,因为它从对象中删除了一个键,但是我觉得打字可能会更好。真的,我希望打字稿能够知道这将返回与传递的类型相同的对象,只是没有指定的键。

我调查了Exclude,它似乎对这种事情很有用,但是很遗憾,我无法对其进行配置。我觉得这是可能的,但是我还没有找到有效实现此目的的方法。有人知道这样做的方法吗?

1 个答案:

答案 0 :(得分:2)

您需要使函数具有通用性,其中一个类型参数用于捕获对象的类型,而一个类型参数用于捕获表示传入的键的字符串文字类型。

const removeKey = <T, K extends keyof T>(
  inputObject: T,
  key: K,
) => {
  if (!inputObject.hasOwnProperty(key)) {
    return inputObject;
  }

  const {
    [key]: _,
    ...rest
  } = inputObject;

  return rest;
};

let a = removeKey({ a: 10, b: 10 }, 'b');
a.a // ok
a.b // err

鉴于您使用了传播,在打字稿3.2中,编译器将自动将函数的返回值键入为Pick<T, Exclude<keyof T, K>>,如果要从类型中删除键K,则需要使用此返回值。 T

修改

适用于2.2(但具有更多类型断言)的版本是:

type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];  
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;  

const removeKey = <T, K extends keyof T>(
    inputObject: T,
    key: K,
): Omit<T, K> => {
    if (!inputObject.hasOwnProperty(key)) {
    return inputObject as any as Omit<T, K>;
    }

    const result = Object.assign({}, inputObject);
    delete result[key]
    return result as any as Omit<T, K>;;
};