Ввод произвольных аргументов функции в качестве типа объекта или кортежа в TypeScript - PullRequest
0 голосов
/ 30 августа 2018

Я ищу что-то вроде этого:

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 {...

тогда ошибка исчезает, что похоже на ошибку

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Вы можете использовать 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

0 голосов
/ 30 августа 2018
type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;

, который предлагается добавить в стандартную библиотеку .

Раунд 2

Когда вы передаете хотя бы один аргумент типа в generate, вы отключаете логический вывод для оставшихся аргументов типа, и используются значения по умолчанию (T = RepoGroupCtor<CanReset>), а RepoGroupCtor<CanReset> принимает параметр rest any[], следовательно нет ошибки Вывод аргумента частичного типа позволит вам избежать этого.

...