typescript 推断常量对象的分部类型

e0bqpujr  于 2022-12-19  发布在  TypeScript
关注(0)|答案(2)|浏览(135)

假设我有一个函数需要某个接口

interface Foo {
  foo: number;
  bar: number;
  baz?: number;
  buz?: number;
}

const doFoo = (params: Foo) => { /* ... */ };

我还有一些常量,其中包含Foo子集的默认值:

const BASE_PROPERTIES = {
  foo: 42,
  baz: 9001,
};

doFoo({
  ...BASE_PROPERTIES,
  bar: -1000
});

这很好用。但是我想知道是否有一种方法可以表示BASE_PROPERTIES包含了Foo的某些部分。既可以在编辑时提供智能感,又可以清楚地说明常量的用途。本质上是一个自动化的Pick<>
我可以

const BASE_PROPERTIES: Partial<Foo> = { /* ... */ }

然而,这将意味着在点差中使用它会给foo带来错误,因为Type 'number | undefined' is not assignable to type 'number'。我可以as anyas Foo它,但如果我实际上忘记包括foo,这将以风险换取便利。
同样,我可以使用pick

const BASE_PROPERTIES: Pick<Foo, 'foo' | 'baz'> = { /* ... */ }

但这要求我在使用时不断更新它(有点麻烦,对于非常大的对象来说并不特别枯燥),而且在添加更多属性时不会给我带来智能,有点挫败了一开始添加它的一半意义。
有没有一种方法可以提示typescript,一个对象应该遵循接口的模式,但是它应该弄清楚const实际上是如何适合接口的?

xxls0lw8

xxls0lw81#

您正在查找Typescript 4.9中引入的satisfies运算符

const BASE_PROPERTIES = {
  foo: 42,
  baz: 9001,
} satisfies Partial<Foo>

这将确保BASE_PROPERTIES * 满足 * 类型Partial<Foo>,同时仍然推断文本类型。
Playground

r8xiu3jd

r8xiu3jd2#

我想你可以用一个小的效用函数来实现

function createBaseProps<K extends keyof Foo>(props: Pick<Foo, K>) {
  return props
}

你应该做智能和类型检查

const BASE_PROPERTIES = createBaseProps({
  foo: 123,
})

并且能够将结果与doFoo示例合并

相关问题