提问人:River H 提问时间:5/29/2019 最后编辑:River H 更新时间:7/5/2019 访问量:277
当参数的类型是泛型时,是否可以在打字稿中为参数设置默认值?
Is it possible to set a default value for an argument in typescript when the type of the argument is a generic?
问:
我正在编写泛型方法,以便在不同的前端应用程序中使用它们,其想法是能够调用函数,预期的响应是 CustomModel 对象。.postAsync<CustomModel>('www.mysite.com',..., CustomModel);
我希望能够为第二个参数设置默认值,以便默认情况下该值将是不同的模型,并且可以在需要时覆盖该值。
如何为接口 Constructable 表示的类型参数设置默认值Constructable<T>
interface Constructable<T> { new(params : any): T ;}
我尝试设置一个接口的默认值,该接口接受一个参数并将参数设置为不同的类型,但我总是收到错误。我还在方法泛型中将 T 的默认类型设置为 CustomModel,然后尝试了这个并得到了同样的错误。Type Constructable<CustomModel> is not assignable to type Constructable<T>
interface Constructable<T> { new(params : any): T ;}
export default class WebapiBase {
static async postAsync<T = CustomModel>(
uri: string,
body: object,
headers: CustomHeaders = new CustomHeaders(),
// This is the part giving errors
model: Constructable<T> = <Constructable<CustomModel>>,): Promise<T> {
return this.requestAsync<T>(model, HTTP_METHOD.POST, uri, headers, body);
}
private static async requestAsync<T>(
model: Constructable<T>,
method: HTTP_METHOD,
uri: string,
headers: CustomHeaders,
body?: object): Promise<T> {
const url = new URL(uri, window.location.origin);
const request = this.buildRequest(url, method, headers, body);
const bodyResponse = await fetch(request)
.then(response => this.validate(response, request.headers))
.then(validResponse => this.extractBody(validResponse))
// Here is where the response body is being used to initialise one of the custom models that we are passing in. Code below
.then(extractedBody => this.buildModel<T>(model, extractedBody))
.catch((error) => { throw this.handleError(error); });
return bodyResponse;
}
private static buildModel<T>(
Model: Constructable<T>,
params: ResponseBody,
): T {
return new Model(params);
}
}
我希望我不必将模型传递给该方法,并且它将始终返回一个 CustomModel 对象。但实际上我得到了这个错误postAsync()
Type Constructable<CustomModel> is not assignable to type Constructable<T>
答:
0赞
River H
7/5/2019
#1
我解决了这个问题,即在模型未传递的情况下返回默认值(在本例中为通用对象)。 通常,修复是:
- 更改不再将模型类型化为接口,而是使用 .
Constructable
Constructable<T> | object
- 更改将模型传递到对象的默认值。
buildModel()
函数检查模型的类型,如果它是一个对象,则返回传入的值,如果它是可构造的,则创建它的实例。
看看它是如何在参数、接口和方法中实现的:postAsync
ResponseModel
buildModel
requestAsync
interface Constructable<T> { new(params : any): T ;}
type ResponseModel<T> = Constructable<T> | Object;
export default class WebapiBase {
static async postAsync<T = Object>(
{
uri = '',
body = {},
headers = new CustomHeaders(),
}: PostRequestParams = {},
// Here is where the defualt is implemented
model: ResponseModel<T> = Object): Promise<T> {
return this.requestAsync(model, HTTP_METHOD.POST, uri, headers, body);
}
private static async requestAsync<T = Object>(
// This param accepts either a class or object
model: ResponseModel<T>,
method: HTTP_METHOD,
uri: string,
headers: CustomHeaders,
body?: object): Promise<T> {
const url = new URL(uri, window.location.origin);
const request = this.buildRequest(url, method, headers, body);
const bodyResponse = await fetch(request)
.then(response => this.validate(response, request.headers))
.then(validResponse => this.extractBody(validResponse))
// Class instance or object returned here
.then(extractedBody => this.buildModel(model, extractedBody))
.catch((error) => { throw this.handleError(error); });
return bodyResponse;
}
// Method that conditionally creates an instance of the passed in model
// Or returns the object passed in if no model specified
private static buildModel<T = Object>(
Model: ResponseModel<T>,
params: any,
): T {
if (typeof Model === 'object') return params;
return new Model(params);
}
}
评论
CustomModel
T
CustomModel
T