看下面的代码:
type Shape = null | string | string[] | { [key: string]: string | string[] }
interface ICfg<InShape extends Shape, OutShape extends Shape> {
shapes?: readonly [InShape, OutShape]
handle?(x: NonNullable<this["shapes"]>[0]): NonNullable<this["shapes"]>[1]
}
function apply<InShape extends Shape, OutShape extends Shape>(cfg: () => ICfg<InShape, OutShape>) {
return cfg()
}
const shape = {
type: "abc",
date: "qwe",
}
var x = apply(() => ({
shapes: [shape, shape],
handle: x => null as any,
}))
变量x
的类型为ICfg<{ type: string; date: string; }, { type: string; date: string; }>
,这很完美。
但是让我们稍微更改一下函数语法:从() => ({ ... })
更改为() => { return { ... } }
:
var y = apply(() => {
return {
shapes: [shape, shape],
handle: x => null as any,
}
})
现在y
的类型是ICfg<Shape, Shape>
,这很糟糕。
实际上,我遇到了更多困难,因为我确实需要将变量shape
放入函数内部(实际上,函数apply
具有参数,而shape
则基于参数): / p>
var z = apply(() => {
const shape = {
type: "abc",
date: "qwe",
}
return {
shapes: [shape, shape],
handle: x => null as any,
}
})
此代码会为变量ICfg<Shape, Shape>
产生相同的z
。
我需要变量z
像ICfg<{ type: string; date: string; }, { type: string; date: string; }>
一样具有类型x
。没有显式指定apply
的通用参数,有什么方法可以实现?