Typescript 根据提供的参数推断返回dict键的类型脚本

Typescript 根据提供的参数推断返回dict键的类型脚本,typescript,Typescript,我有以下文件: 类型.ts 梅因酒店 在typescript中是否可以为我的Api变量设置类型完成?我希望能够知道哪些函数在我的API中可用,最重要的是每个API调用的参数,而不必查看定义API规范的文件。但是,仅在类型中使用[T in keyof ApiSpec]无法推断我要传递给createApi的API规范的确切键。这在typescript中是可能的吗 注意:我使用的是2.3.4版,目前无法更新到最新的typescript版本您需要使用泛型类型参数来捕获传入createApi的实际类型,并

我有以下文件:

类型.ts

梅因酒店

在typescript中是否可以为我的
Api
变量设置类型完成?我希望能够知道哪些函数在我的API中可用,最重要的是每个API调用的参数,而不必查看定义API规范的文件。但是,仅在类型中使用
[T in keyof ApiSpec]
无法推断我要传递给
createApi
的API规范的确切键。这在typescript中是可能的吗


注意:我使用的是2.3.4版,目前无法更新到最新的typescript版本

您需要使用泛型类型参数来捕获传入
createApi
的实际类型,并将其映射到
APIRESQUEST
中,而不是泛型
ApiSpec
ApiSpec
可用作类型参数的类型约束

export interface ApiSpec {
    [apiReq: string]: (...args: any[]) => {
        url: string;
        contentType?: string;
        query?: {
            [key: string]: any;
        };
        method?: string;
    };
}

export type ApiRequest<T extends ApiSpec> = {
    [P in keyof T]: (...args: Parameters<T[P]>) => Promise<any>;
};



export default function createApi<T extends ApiSpec>(apiSpec: T, concurrent: boolean = false): ApiRequest<T> {
    return null!; // implementation 
}
// usually defined in a separate file
const ApiSpec = {
    fetchData: (start: Date, end: Date) => {
        return {
            url: `/fetchData?start=${start}&end=${end}`
        };
    }
};
const Api = createApi(ApiSpec);

Api.fetchData(new Date(), new Date()).then(res => {
    // do something with result
})
导出接口ApiSpec{
[apiReq:string]:(…args:any[])=>{
url:string;
contentType?:字符串;
查询?:{
[键:字符串]:任意;
};
方法?:字符串;
};
}
导出类型请求={
[P in keyof T]:(…args:Parameters)=>Promise;
};
导出默认函数createApi(apiSpec:T,concurrent:boolean=false):ApiRequest{
返回null!;//实现
}
//通常在单独的文件中定义
常数ApiSpec={
fetchData:(开始:日期,结束:日期)=>{
返回{
url:`/fetchData?start=${start}&end=${end}`
};
}
};
const Api=createApi(ApiSpec);
获取数据(new Date(),new Date())。然后(res=>{
//做一些有结果的事情
})
注意我还添加了
参数
,以便在结果对象中保留参数类型

编辑 对于您正在使用的typescript版本(2.3),rest参数中没有条件类型或元组,因此很遗憾,无法以类型安全的方式映射函数参数。我们所能做的就是:

export type ApiRequest<T extends ApiSpec> = {
    [P in keyof T]: (...args: any[]) => Promise<any>;
};
导出类型请求={
[P in keyof T]:(…args:any[])=>承诺;
};

听起来像是从运行时数据源中寻找开发时间类型的完成。我误解了吗?什么是参数?我得到
无法找到名称参数
error@XeniaSis您使用的是什么版本的ts<代码>参数我想是在3.2(或3.1)中添加的,但是它的定义
类型参数any>=T扩展了(…args:inferp)=>any?P:从来没有应该适用于我在使用v2的帖子中提到的3.0及以上版本。3@XeniaSis这是相当古老的,让我看看,如果我可以得到类似的工作在该版本(这将是相当丑陋的,虽然)。很抱歉,我错过了问题中的版本。它在计划更新中。因此,感谢您给出了涵盖这两个版本的答案:)
import createApi from './Api';

// usually defined in a separate file
const ApiSpec = {
    fetchData: (start: Date, end: Date) => {
        return {
            url: `/fetchData?start=${start}&end=${end}`
        };
    }
};
const Api = createApi(ApiSpec);

Api.fetchData(new Date(), new Date()).then(res => {
    // do something with result
})
export interface ApiSpec {
    [apiReq: string]: (...args: any[]) => {
        url: string;
        contentType?: string;
        query?: {
            [key: string]: any;
        };
        method?: string;
    };
}

export type ApiRequest<T extends ApiSpec> = {
    [P in keyof T]: (...args: Parameters<T[P]>) => Promise<any>;
};



export default function createApi<T extends ApiSpec>(apiSpec: T, concurrent: boolean = false): ApiRequest<T> {
    return null!; // implementation 
}
// usually defined in a separate file
const ApiSpec = {
    fetchData: (start: Date, end: Date) => {
        return {
            url: `/fetchData?start=${start}&end=${end}`
        };
    }
};
const Api = createApi(ApiSpec);

Api.fetchData(new Date(), new Date()).then(res => {
    // do something with result
})
export type ApiRequest<T extends ApiSpec> = {
    [P in keyof T]: (...args: any[]) => Promise<any>;
};