TypeScript:在函数中强制使用通用推断的类型参数

埃里克·阿莫迪奥

有没有一种方法可以限制run下面调用,使其严格指定给类型参数指定的类型所允许的类型RequestType<>返回类型R似乎可行,但RQ并不严格。

class RequestType<RQ, R> {
    constructor(public readonly method: string) { }
 }

interface FooRequest {
    foo: string;
    bar: string;
}

interface FooResponse {
    foobar: string;
}

const FooRequestType = new RequestType<FooRequest, FooResponse>("foo");

function run<RQ, R>(type: RequestType<RQ, R>, request: RQ): R {
    // real code here
    return {} as R;
}

这是电话

const foo1 = run(FooRequestType, {}); // want an error here
const foo2 = run(FooRequestType, {
    foo: "foo" // want an error here
});
const foo3 = run(FooRequestType, {
    foo: "foo",
    bar: "bar",
    baz: "" // error here -- good
});

这是TypeScript玩具的链接任何帮助表示赞赏-谢谢!

马克西瓦沃(Maciek Wawro)

来自docs因为TypeScript是结构类型系统,所以类型参数仅在作为成员类型的一部分使用时才影响结果类型。

就您而言,RequestType<{},FooResponse>并且RequestType<FooRequest, FooResponse>具有完全相同的结构,因此

run(FooRequestType, {});

类型正确推断为

run<{},FooResponse>(FooRequestType: RequestType<{}, FooResponse>, {}: {})


解决该问题的一种方法是向中添加一些(如果需要,则是伪造的)属性,以RequestType使其RequestType<RQ1,R>不同于RequestType<RQ2,R>该财产可能是

class RequestType<RQ, R> {
    private readonly acc: (req: RQ) => RQ | undefined;
    constructor(public readonly method: string) { }
}

请注意,要使此特定解决方案成功,您需要启用strictFunctionTypesoption。否则,(req: FooRequest) => FooRequest将可分配给(req: {}) => {},因此FooRequestType仍将可分配给RequestType<{}, FooResponse>您可以在此处了解更多信息


一种不同的方法是不允许TypeScript为推断错误的类型request,而是使其推断为的类型requestTypetype出于可读性而更改):

type RequestOf<RT> = RT extends RequestType<infer RQ, any> ? RQ : never;
type ResponseOf<RT> = RT extends RequestType<any, infer R> ? R : never;
function run<RT extends RequestType<any, any>>(
    requestType: RT,
    request: RequestOf<RT>
): ResponseOf<RT> {
    return {} as ResponseOf<RT>;
}

现在,TypeScript将正确地“猜测”RTRequestType<FooRequest, FooResponse>然后,

type RequestOf<RT> = RT extends RequestType<infer RQ, any> ? RQ : never;

基本上说:如果RTRequestType<RQ, something>,则RequestOf<RT>等于RQ有关该infer魔术的更多信息,请参见条件类型中的类型推断

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在TypeScript中推断通用函数类型

TypeScript:从错误的参数推断出通用函数类型参数

使用Typescript中的函数参数隐式类型推断

函数的类型推断作为 Typescript 中的参数

在多个级别的TypeScript中推断通用类型参数

从函数参数推断通用类型之一

来自特定函数参数的通用类型推断

TypeScript:将此多态并推断通用函数参数

TypeScript中必需的类型与推断的通用类型

根据TypeScript中的另一个通用参数推断通用类型参数

Typescript使用条件类型推断构造函数参数

推断TypeScript中的函数参数

如何在Typescript函数类型中强制使用强制性参数?

TypeScript通用类型推断

TypeScript通用类型推断

Typescript从实现中推断通用类型

为什么在实现通用接口时TypeScript无法推断函数参数的类型?

从枚举参数推断Typescript函数返回类型

我可以使用类型作为值(或从构造函数参数正确推断通用类类型)吗?

基于其参数类型的函数类型参数的TypeScript类型推断

从单个构造函数参数推断通用类类型参数

通过Typescript中的其他函数参数推断函数参数的类型

函数上的C#可选参数丢失通用类型推断

推断TypeScript中的接口类型参数

TypeScript函数无法从超级接口推断通用参数

推断 typescript 通用包装函数返回类型属性值

TypeScript从使用的参数推断返回类型

Typescript使用Compiler API推断类型参数

为什么在通用函数类型参数推断中,Scala无法将Null类型识别为T的子类型?