在传递默认值的同时,一般性地键入一个参数



我正在尝试编写一个nest()函数,该函数接受2个对象实体和一个键,并将第二个嵌套在提供的键中的第一个中。

实体1

{
"foo": "bar"
}

实体2

{
"few": "baz"
}

实体2嵌套在wow中的实体1中

{
"foo": "bar",
"wow": {
"few": "baz"
}
}

我带来了以下实现,它的工作原理就像一个魅力

type Nested <
LeftEntity extends Record<string, unknown>,
RightEntity extends Record<string, unknown>,
NestKey extends string
> = LeftEntity & {
[Key in NestKey]: RightEntity
}
const nest = <
LeftEntity extends Record<string, unknown>,
RightEntity extends Record<string, unknown>,
NestKey extends string
> (
leftEntity: LeftEntity,
rightEntity: RightEntity,
nestKey: NestKey
): Nested<LeftEntity, RightEntity, NestKey> => {
const nested = {
...leftEntity,
[nestKey]: rightEntity
} as Nested<LeftEntity, RightEntity, NestKey>
return nested
}

现在我想给nestKey一个默认值,并将其作为一个可选参数。因此,我天真地尝试:

const nest = <
LeftEntity extends Record<string, unknown>,
RightEntity extends Record<string, unknown>,
NestKey extends string
> (
leftEntity: LeftEntity,
rightEntity: RightEntity,
nestKey: NestKey = 'meta' // <= HERE
): Nested<LeftEntity, RightEntity, NestKey> => {
// ...
}

但编译器抱怨道:

TS2322:无法将类型"string"分配给类型"NestKey"。"string"可以分配给类型约束"NestKey",但"NestKey"可以用约束"string"的不同子类型实例化。

虽然我完全理解为什么会抱怨(我理解,这不是我的问题(;我想知道实现我想要的目标的模式是什么。

我想为解决方案添加一些限制:

  • 尽可能避免使用类型转换
  • 具有完美的返回类型类型(特别是使用vscode使其自动完成(

这可能吗?

我设法实现了它,泛型类型可以省略,nestKey也可以省略,如果泛型参数被省略或提供为"元";

Playgorund链接

const nest = <
LeftEntity extends Record<string, unknown>,
RightEntity extends Record<string, unknown>,
NestKey extends string = "meta" // default meta
> (
leftEntity: LeftEntity,
rightEntity: RightEntity,
nestKey: NestKey = "meta" as NestKey //default meta
): Nested<LeftEntity, RightEntity, NestKey> => {
const nested = {
...leftEntity,
[nestKey]: rightEntity
} as Nested<LeftEntity, RightEntity, NestKey>
return nested
}

如果你这样尝试,它会抱怨

const a = nest<
{hey: string},
{ho: string}
>(
{hey: 'foo'},
{ho: 'bar'},
"aaa"
)

最新更新