typescript在返回类型中引用自己的类型
我有一个基类模型:typescript在返回类型中引用自己的类型,typescript,Typescript,我有一个基类模型: class ApiModel { static async fetch (params = {}, Model = this, apiPath = this.apiPath): Promise<any[] | PaginatedResponse> { let { data } = await axios.get(apiPath, { params }) return Model.transformResponse(data)
class ApiModel {
static async fetch (params = {}, Model = this, apiPath = this.apiPath): Promise<any[] | PaginatedResponse> {
let { data } = await axios.get(apiPath, { params })
return Model.transformResponse(data)
}
}
Typescript不喜欢将我的返回定义(any[])与变量类型用户组合使用:
let users: User[] = await User.fetch() // Assigned expression type any[] | PaginatedResponse is not assignable to type User[]
如何替换
任何[]
而不显式使用用户[]
(它需要是泛型的,基于扩展类)您得到的错误不是由于任何[]
而不是用户[]
引起的,而是由于与分页响应的联合
any[]
和PaginatedResponse
之间的联合将不可分配给用户[]
。您需要使用类型保护来区分数组结果和分页响应
因此,这将与any[]
一起工作(因为any
可分配给任何其他类型,包括User
)
也就是说,您仍然应该避免使用any
(就像瘟疫一样,如果您不知道类型,请选择unknown
(请参阅unknown vs any))
要在静态方法中获取当前类的类型,可以将泛型类型参数与this
参数注释结合使用
确切的解决方案可能因类是否抽象、构造函数是否具有参数(以及派生类型是否具有不同的参数签名)而异
下面的解决方案适用于非抽象基类,并且如果派生类与基类具有相同的构造函数签名(或兼容),则可以使用
interface PaginatedResponse<T> {
start: number;
end: number;
data: T[]
}
class ApiModel {
static apiPath = ""
static async fetch<T extends typeof ApiModel>(this: T, params = {}, Model = this, apiPath = this.apiPath): Promise<Array<InstanceType<T>> | PaginatedResponse<InstanceType<T>>> {
return null!;
}
}
class User extends ApiModel {
}
(async function (){
let result = await User.fetch()
if(result instanceof Array) {
const user = result; // is User[]
}else {
const paged = result; // PaginatedResponse<User>
}
})()
接口分页响应{
开始:编号;
完:编号;;
数据:T[]
}
类API模型{
静态apiPath=“”
静态异步获取(this:T,params={},Model=this,apiPath=this.apiPath):承诺{
返回null!;
}
}
类用户扩展ApiModel{
}
(异步函数(){
let result=await User.fetch()
if(数组的结果实例){
const user=result;//是用户[]
}否则{
const paged=result;//分页响应
}
})()
注:我用一个界面填写了
PaginatedResponse
,因为我不确定该类型是什么样的,如果该类型在您的控制下,我会将其设置为泛型以反映返回的结果类型。FYI:您得到的错误不是由于any[]
vsUser[]
这是由于与PaginatedResponse
的联合PaginatedResponse
来自哪里?允许模型类型不是也应该是泛型的吗?我可以提供如何使基类上的静态方法适用于派生类的解决方案,但是您的代码还有其他问题
let result = await User.fetch()
if(result instanceof Array) {
const user: User[] = result;
}else {
const paged = result;
}
interface PaginatedResponse<T> {
start: number;
end: number;
data: T[]
}
class ApiModel {
static apiPath = ""
static async fetch<T extends typeof ApiModel>(this: T, params = {}, Model = this, apiPath = this.apiPath): Promise<Array<InstanceType<T>> | PaginatedResponse<InstanceType<T>>> {
return null!;
}
}
class User extends ApiModel {
}
(async function (){
let result = await User.fetch()
if(result instanceof Array) {
const user = result; // is User[]
}else {
const paged = result; // PaginatedResponse<User>
}
})()