TypeScript对类型约束的推断

教堂

我有一些描述Api呼叫的类型。举个例子:

export class RequestType {
  prop1: string;
  prop2: string;
}

export class ResponseType {
  prop3: string;
  prop4: string;
}

每个请求类型都链接到响应类型。我当前正在做的是定义一个接口IReturn<T>并将其添加到请求类型:

export interface IReturn<T> {}

export class RequestType implements IReturn<ResponseType> {
  prop1: string;
  prop2: string;
}

然后我有一个服务,我想有一个方法可以从请求类型的构造函数中推断出请求类型和响应类型:

import { RequestType, IReturn } from './dto';

export class SomeService {
    callApi<TRequest extends IReturn<TResponse>, TResponse>(dto: Request) TResponse {
      // implementation
    }
}

但是,当我尝试调用该服务时,TypeScript可以正确推断TRequest,但是TResponse绑定到{}

// response is a {} and not a ResponseType!!
const response = this.someService.call(requestInstance);

现在,我有点茫然。我怎么能既重构的服务,以获得类型推断的接口或DTOS请求和响应类型?

提香·切尔尼科娃·德拉戈米尔

这里有几个问题,第一个是您有未使用的泛型参数,因为typescript使用结构化类型系统,这些几乎被忽略。您可以在此常见问题解答中看到此文档第二个问题是,打字稿不会做类型推断猜测TResponse时,TRequest extends IReturn<TResponse>它只会去尽可能简单的TResponse通常是{}

为了克服这些限制,我们可以首先在中使用type参数IReturn<T>,例如,我们可以有一个字段表示的构造函数T(但实际上任何用法都可以,即使是假的也可以_unusedField: T)。而对于第二个问题,我们可以使用条件类型来提取T来自IReturn<T>

export class ResponseType {
    prop3: string;
    prop4: string;
}

export interface IReturn<T> { returnCtor : new (...args: any[] ) => T; }

export class RequestType implements IReturn<ResponseType> {
    returnCtor = ResponseType;
    prop1!: string;
    prop2!: string;
}

export class SomeService {
    callApi<TRequest extends IReturn<any>>(dto: TRequest) : TRequest extends IReturn<infer U> ? U : never {
        return null as any
    }
}

const someService = new SomeService;
const requestInstance = new RequestType;
const response = someService.callApi(requestInstance);

游乐场链接

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章