在Typescript中的对象中需要0个或多个键

gz5pxeao  于 2023-04-07  发布在  TypeScript
关注(0)|答案(1)|浏览(95)

我试图输入一个函数,它接受一个具有特定键的对象,但我希望我的开发人员也能够保留这些键未定义,以便在使用特定键的情况下抛出错误。
但是我不知道如何不需要所有的键。这是我的代码:

type Keys = "One" | "Two" | "Three"

export const getConfig = (
  key: Keys,
  config: {
    [key in Keys]: AnotherType;
  }
) => {
  if (!config[key]) {
    throw new Error(`Could not find config.`);
  }

  return config[key];
};

我希望这个函数可以这样使用:

getConfig('One', {
    One: {},
    Three: {}
}

但显然这给了我以下错误:

Property 'Two' is missing in type

我尝试了undefined的任何组合,但无法让它工作。
当前的解决方法如下所示:

getConfig('One', {
    One: {},
    Two: null as unknown as any,
    Three: {}
}

但显然不是很好的DX...
我怎么才能让它工作?

kmbjn2e3

kmbjn2e31#

有很多解决方案,取决于你将如何使用该功能。
一个是将config定义为Record<string, AnotherType>,因为您将检查函数中的键是否存在。

export const getConfig = (key: Keys, config: Record<string, AnotherType>) => {
    // ...
};

你可能想限制config的密钥(帖子中的原始问题),你可以组合PartialRecord来做到这一点:

export const getConfig = (key: Keys, config: Partial<Record<Keys, AnotherType>>) => {
    // ...
};

但是,这会将返回类型变为AnotherType|undefined,因为Partial
最后一个是使用泛型进行静态检查,确保key存在于config对象中,此解决方案跳过了运行时检查(throw ...

export const getConfig = <T extends Keys, Config extends Record<T, AnotherType>>(key: T, config: Config) => {
    return config[key] // Config[T] (AnotherType)
};

另一种只有一个类型参数的泛型函数:

export const getConfig = <Config extends Partial<Record<Keys, AnotherType>>>(key: keyof Config, config: Config) => {
    return config[key]
};

相关问题