繁体   English   中英

在TypeScript中将任意函数参数推断为对象或元组类型

[英]Inferring arbitrary function arguments as object or tuple type in TypeScript

我正在寻找这种类型的东西:

type ArgsType<F extends Function> = ...

哪里

ArgsType<(n: number, s: string)=>void>

会给我

[number, string]

要么

{n: number, s: string}

基于答案之一,我创建了以下类型:

type ArgsType<F extends (...x: any[]) => any>
    = F extends (...x: infer A) => any ? A : never;

type CtorArgsType<F extends new (...x: any[]) => any>
    = F extends new (...x: infer A) => any ? A : never;


interface RepoGroup {
    resetAsync?: () => Promise<void>
}

interface RepoGroupOptions<Reset extends "CanReset" | "CannotReset"="CannotReset"> {
    reset: Reset extends "CanReset" ? () => Promise<void> : undefined
}

type RepoGroupCtor<Reset extends "CanReset" | "CannotReset"="CannotReset">
    = new (...args: any[]) => RepoGroupOptions<Reset>


export function generate<
    CanReset extends "CanReset" | "CannotReset"="CannotReset",
    T extends RepoGroupCtor<CanReset>=RepoGroupCtor<CanReset>
    >(args: T) {
    return class implements RepoGroup {
        private args: InstanceType<T>
        constructor(...config: CtorArgsType<T>) {
            this.args = new args(config) as any
        }

        resetAsync = this.args.reset
    }
}


export const Repo = generate(class {
    readonly baseUrl: string
    constructor(args: { apiBaseUrl: string }) {
        this.baseUrl = args.apiBaseUrl
    }

    reset: undefined
})

let repository = new Repo()

最后一行显示了应有的错误。 但是,如果我仅向仓库添加通用参数,则:

export const Repo = generate<"CannotReset">(class {...

然后错误消失了,好像是个错误

type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;

建议将其添加到标准库中

第二回合

当您传递至少一个类型参数以generate ,您将关闭对其余类型参数的推断,并使用默认值( T = RepoGroupCtor<CanReset> ),并且RepoGroupCtor<CanReset>接受any[]的其余参数,因此没错。 部分类型参数推断将为您提供避免这种情况的方法。

您可以使用Parameters<T> 从(至少)3.2起可用

用法:


function log(s: string) { console.log(s)}
type LogArg = Parameters<typeof log>[0]; // string

interface Logger {
 log(s: string) => void;
}
type LogArg2 = Parameters<Logger['log']>[0]; // string

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM