代码之家  ›  专栏  ›  技术社区  ›  Chris

类型脚本引用返回类型中的自己的类型

  •  1
  • Chris  · 技术社区  · 6 年前

    我有一个基本类APIModel:

    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 User extends ApiModel {
    }
    

    typescript不喜欢我的返回定义(any[])与变量类型user的组合:

    let users: User[] = await User.fetch() // Assigned expression type any[] | PaginatedResponse is not assignable to type User[]
    

    我怎么换 any[] 没有明确使用 User[] (它需要是通用的,基于扩展类)

    1 回复  |  直到 6 年前
        1
  •  2
  •   Titian Cernicova-Dragomir    6 年前

    你得到的错误不是由于 any[] VS User[] 它是由于与 PaginatedResponse .

    之间的联盟 任何[ ] 聚腺苷酸酶 不可转让给 用户[ ] . 您需要使用类型保护来区分数组结果和 聚腺苷酸酶

    所以这将与 任何[ ] (自 any 可分配给任何其他类型,包括 User )

    let result = await User.fetch()
    if(result instanceof Array) {
        const user: User[] = result;
    }else {
        const paged = result;
    }
    

    尽管如此,你还是应该避免 任何 (就像瘟疫一样,如果你不知道喜欢哪种类型的话 unknown (见 here 对于未知与任何)

    要获取静态方法中当前类的类型,可以将泛型类型参数与 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>
        }
    })()
    

    我填写的注释 聚腺苷酸酶 对于接口,因为我不确定该类型是什么样子的,如果该类型在您的控制下,我将使其成为通用的,以反映返回的结果类型。