当试图将泛型Merge的结果赋值为对象类型(键值类型)时,会出现语法错误:
type Merge<a,b> = any
type test<P, S= any, K= any> = {
jsx1?: (state: Merge<K, S>, props: P, nextJsx?) => JSX.Element; //ok
jsx2?: ({state: S, props: P, nextJsx}) => JSX.Element; // ok
jsx3?: ({ state: Merge<K, S>, props: P, nextJsx }) => JSX.Element; // error - why?
// ^ WebStorm: ", expected" ^ VSCode: ';' expected.(1005)
};为什么这被认为是语法错误?如何将jsx3->state分配给Merge类型
TypeScript 4.4.4.
TS游乐场:
发布于 2021-11-30 14:32:07
在签名({state: S, props: P, nextJsx}) => JSX.Element中,S和P不是类型,它们是标识符。在这个上下文中,冒号:并不意味着类型注释,它意味着重新绑定属性的名称,如下面的示例所示:
const obj = {foo: 23};
// bar is not a type annotation here
const {foo: bar} = obj;
// 23
console.log(bar);我不知道参数重新绑定在类型声明中有什么用处,但无论好坏,这就是它的含义。因此,错误是因为Merge<K, S>不是重新绑定的有效标识符;但实际上,您的jsx2和jsx3声明都有问题,只是没有得到另一个错误。
解决方案是将类型放在上下文中它们实际上是类型的位置;即在参数的类型注释中。
type Test<P, S=any, K=any> = {
jsx1?: (state: Merge<K, S>, props: P, nextJsx?) => JSX.Element;
jsx2?: (params: {state: S, props: P, nextJsx}) => JSX.Element;
jsx3?: (params: {state: Merge<K, S>, props: P, nextJsx}) => JSX.Element;
}注意,该参数是一个名为params的单个对象,其类型现在发生在类型注释上下文中,因此不被解析为重新绑定标识符。此外,尽管类型声明中只有一个命名参数params,但在实际实现这些函数时仍然完全可以执行参数析构(和重新绑定,如果您愿意):
const test: Test<number, number, number> = {
jsx2: ({state, props, nextJsx}) => console.log(state, props, nextJsx),
jsx3: ({state, props, nextJsx}) => console.log(state, props, nextJsx),
};发布于 2021-11-30 14:28:46
在jsx2和jsx3中使用不同的名称来销毁对象,而不是键入它们。对于jsx3,这是无效的语法。您想要做的是正确地键入函数参数:
type Merge<A,B> = any;
type JSX2Args<P, S> = {
state: S,
props: P,
nextJsx: unknown
}
type JSX3Args<P, S, K> = {
state: Merge<K, S>,
props: P,
nextJsx: unknown
}
type test<P, S= any, K= any> = {
jsx1?: (state: Merge<K, S>, props: P, nextJsx?) => JSX.Element;
jsx2?: (arg: JSX2Args<P, S>) => JSX.Element;
jsx3?: ({ state, props, nextJsx }: JSX3Args<P, S, K>) => JSX.Element;
};https://stackoverflow.com/questions/70170834
复制相似问题