(TypeScript) 参数从其兄弟(所有这些都是 fns)return 类型的联合中获取其类型
(TypeScript) argument gets its type from the union of its sibling's (all of which are fns) return types
我正在尝试创建一个接受两个参数的通用函数,第一个参数是一个函数数组。第二个参数的类型应该是第一个参数元素的 return 类型的联合(所有这些都是函数)。
这是我试过的方法:
type Fn<R> = () => R;
const a: Fn<true> = () => true;
const b: Fn<"somen"> = () => "somen";
interface C<ABUnion, ABReturnUnion> {
fns: ABUnion[];
returns: ABReturnUnion;
}
function getX<R>(fns: Array<Fn<R>>, returns: R) {
type FnsUnion = typeof fns[number];
const c: C<FnsUnion, R> = {
fns,
returns,
};
return c;
}
getX([b, a], "true");
语言服务在 getX
调用中加下划线 b
,并显示以下错误:
Type '"somen"' is not assignable to type 'true'.
有人知道解决方案吗?谢谢!
当编译器在那里看到异构数组文字时,它会使用一些试探法来确定是为元素类型合成联合,还是在第一个与推断类型不匹配的元素上发出错误。这是一个权衡,因为有时你想要这样的错误。例如,下面的错误通常被认为是可取的,如前所述 :
function same<T>(x: T, y: T) { };
same(0, ""); // error!
// ---> ~~
// argument of type "" is not assignable to number
该函数可以像这样变成一个数组示例:
function sameTuple<T>(x: [T, T]) { };
sameTuple([0, ""]); // error!
// ---------> ~~
// Type 'string' is not assignable to type 'number'.
你可以看到困境...有时人们希望 T
成为联合,而其他时候人们希望限制对同构数组的调用。
在这种情况下,我建议将 fns
的类型更改为编译器愿意为其推断更广泛泛型的类型。例如:
function getX<F extends Array<() => any>>(fns: F, returns: ReturnType<F[number]>) {
const c: C<F[number], ReturnType<F[number]>> = {
fns,
returns,
};
return c;
}
这里的通用类型 F
应该是任何与无参数函数数组匹配的东西。这是从fns
的类型推断出来的最直接的东西。一旦成功,您就可以将 returns
的自己的类型合成为 ReturnType<F[number]>
。
现在它应该可以如您所愿地工作了,我认为:
getX([b, a], "somen"); // okay
getX([b, a], "true"); // error!
// --------> ~~~~~~
// "true" is not assignable to true | "somen".
好的,希望对你有帮助;祝你好运!
我正在尝试创建一个接受两个参数的通用函数,第一个参数是一个函数数组。第二个参数的类型应该是第一个参数元素的 return 类型的联合(所有这些都是函数)。
这是我试过的方法:
type Fn<R> = () => R;
const a: Fn<true> = () => true;
const b: Fn<"somen"> = () => "somen";
interface C<ABUnion, ABReturnUnion> {
fns: ABUnion[];
returns: ABReturnUnion;
}
function getX<R>(fns: Array<Fn<R>>, returns: R) {
type FnsUnion = typeof fns[number];
const c: C<FnsUnion, R> = {
fns,
returns,
};
return c;
}
getX([b, a], "true");
语言服务在 getX
调用中加下划线 b
,并显示以下错误:
Type '"somen"' is not assignable to type 'true'.
有人知道解决方案吗?谢谢!
当编译器在那里看到异构数组文字时,它会使用一些试探法来确定是为元素类型合成联合,还是在第一个与推断类型不匹配的元素上发出错误。这是一个权衡,因为有时你想要这样的错误。例如,下面的错误通常被认为是可取的,如前所述
function same<T>(x: T, y: T) { };
same(0, ""); // error!
// ---> ~~
// argument of type "" is not assignable to number
该函数可以像这样变成一个数组示例:
function sameTuple<T>(x: [T, T]) { };
sameTuple([0, ""]); // error!
// ---------> ~~
// Type 'string' is not assignable to type 'number'.
你可以看到困境...有时人们希望 T
成为联合,而其他时候人们希望限制对同构数组的调用。
在这种情况下,我建议将 fns
的类型更改为编译器愿意为其推断更广泛泛型的类型。例如:
function getX<F extends Array<() => any>>(fns: F, returns: ReturnType<F[number]>) {
const c: C<F[number], ReturnType<F[number]>> = {
fns,
returns,
};
return c;
}
这里的通用类型 F
应该是任何与无参数函数数组匹配的东西。这是从fns
的类型推断出来的最直接的东西。一旦成功,您就可以将 returns
的自己的类型合成为 ReturnType<F[number]>
。
现在它应该可以如您所愿地工作了,我认为:
getX([b, a], "somen"); // okay
getX([b, a], "true"); // error!
// --------> ~~~~~~
// "true" is not assignable to true | "somen".
好的,希望对你有帮助;祝你好运!