Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
typescript在返回类型中引用自己的类型_Typescript - Fatal编程技术网

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[]
vs
User[]
这是由于与
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>
    }
})()