diff --git a/index.d.ts b/index.d.ts index c78972fdf..53261cb1b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -403,9 +403,10 @@ export type Implementation = (t: ExecutionContext) => Imp export type CbImplementation = (t: CbExecutionContext) => ImplementationResult; /** A reusable test or hook implementation. */ -export interface Macro { - (t: ExecutionContext, ...args: Args): ImplementationResult; +export type UntitledMacro = (t: ExecutionContext, ...args: Args) => ImplementationResult; +/** A reusable test or hook implementation. */ +export type Macro = UntitledMacro & { /** * Implement this function to generate a test (or hook) title whenever this macro is used. `providedTitle` contains * the title provided when the test or hook was declared. Also receives the remaining test arguments. @@ -413,56 +414,33 @@ export interface Macro { title?: (providedTitle: string | undefined, ...args: Args) => string; } +export type EitherMacro = Macro | UntitledMacro; + /** Alias for a single macro, or an array of macros. */ -export type OneOrMoreMacros = Macro | [Macro, ...Macro[]]; +export type OneOrMoreMacros = EitherMacro | [EitherMacro, ...EitherMacro[]]; /** A reusable test or hook implementation, for tests & hooks declared with the `.cb` modifier. */ -export interface CbMacro { - (t: CbExecutionContext, ...args: Args): ImplementationResult; +export type UntitledCbMacro = (t: CbExecutionContext, ...args: Args) => ImplementationResult + +/** A reusable test or hook implementation, for tests & hooks declared with the `.cb` modifier. */ +export type CbMacro = UntitledCbMacro & { title?: (providedTitle: string | undefined, ...args: Args) => string; } -/** Alias for a single macro, or an array of macros, used for tests & hooks declared with the `.cb` modifier. */ -export type OneOrMoreCbMacros = CbMacro | [CbMacro, ...CbMacro[]]; - -/** Infers the types of the additional arguments the macro implementations should be called with. */ -export type InferArgs = - OneOrMore extends Macro ? Args : - OneOrMore extends Macro[] ? Args : - OneOrMore extends CbMacro ? Args : - OneOrMore extends CbMacro[] ? Args : - never; - -export type TitleOrMacro = string | OneOrMoreMacros - -export type MacroOrFirstArg = - TitleOrMacro extends string ? OneOrMoreMacros : - TitleOrMacro extends OneOrMoreMacros ? InferArgs[0] : - never - -export type TitleOrCbMacro = string | OneOrMoreCbMacros +export type EitherCbMacro = CbMacro | UntitledCbMacro; -export type CbMacroOrFirstArg = - TitleOrMacro extends string ? OneOrMoreCbMacros : - TitleOrMacro extends OneOrMoreCbMacros ? InferArgs[0] : - never - -export type RestArgs = - MacroOrFirstArg extends OneOrMoreMacros ? InferArgs : - MacroOrFirstArg extends OneOrMoreCbMacros ? InferArgs : - TitleOrMacro extends OneOrMoreMacros ? Tail> : - TitleOrMacro extends OneOrMoreCbMacros ? Tail> : - never +/** Alias for a single macro, or an array of macros, used for tests & hooks declared with the `.cb` modifier. */ +export type OneOrMoreCbMacros = EitherCbMacro | [EitherCbMacro, ...EitherCbMacro[]]; export interface TestInterface { /** Declare a concurrent test. */ (title: string, implementation: Implementation): void; /** Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void /** Declare a concurrent test that uses one or more macros. The macro is responsible for generating a unique test title. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that is run once, after all tests have passed. */ after: AfterInterface; @@ -499,10 +477,10 @@ export interface AfterInterface { (title: string, implementation: Implementation): void; /** Declare a hook that is run once, after all tests have passed. Additional arguments are passed to the macro. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that is run once, after all tests have passed. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that is run once, after all tests are done. */ always: AlwaysInterface; @@ -521,10 +499,10 @@ export interface AlwaysInterface { (title: string, implementation: Implementation): void; /** Declare a hook that is run once, after all tests are done. Additional arguments are passed to the macro. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that is run once, after all tests are done. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that must call `t.end()` when it's done. */ cb: HookCbInterface; @@ -540,10 +518,10 @@ export interface BeforeInterface { (title: string, implementation: Implementation): void; /** Declare a hook that is run once, before all tests. Additional arguments are passed to the macro. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that is run once, before all tests. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; /** Declare a hook that must call `t.end()` when it's done. */ cb: HookCbInterface; @@ -559,13 +537,13 @@ export interface CbInterface { * Declare a concurrent test that uses one or more macros. The macros must call `t.end()` when they're done. * Additional arguments are passed to the macro. */ - , MoA extends CbMacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreCbMacros, ...rest: T): void; /** * Declare a concurrent test that uses one or more macros. The macros must call `t.end()` when they're done. * The macro is responsible for generating a unique test title. */ - (macro: OneOrMoreCbMacros<[], Context>): void + (macros: OneOrMoreCbMacros, ...rest: T): void; /** Declare a test that is expected to fail. */ failing: CbFailingInterface; @@ -582,13 +560,13 @@ export interface CbFailingInterface { * Declare a test that uses one or more macros. The macros must call `t.end()` when they're done. * Additional arguments are passed to the macro. The test is expected to fail. */ - , MoA extends CbMacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreCbMacros, ...rest: T): void; /** * Declare a test that uses one or more macros. The macros must call `t.end()` when they're done. * The test is expected to fail. */ - (macro: OneOrMoreCbMacros<[], Context>): void + (macros: OneOrMoreCbMacros, ...rest: T): void; only: CbOnlyInterface; skip: CbSkipInterface; @@ -604,13 +582,13 @@ export interface CbOnlyInterface { * Declare a test that uses one or more macros. The macros must call `t.end()` when they're done. * Additional arguments are passed to the macro. Only this test and others declared with `.only()` are run. */ - , MoA extends CbMacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreCbMacros, ...rest: T): void; /** * Declare a test that uses one or more macros. The macros must call `t.end()` when they're done. * Additional arguments are passed to the macro. Only this test and others declared with `.only()` are run. */ - (macro: OneOrMoreCbMacros<[], Context>): void + (macros: OneOrMoreCbMacros, ...rest: T): void; } export interface CbSkipInterface { @@ -618,10 +596,10 @@ export interface CbSkipInterface { (title: string, implementation: CbImplementation): void; /** Skip this test. */ - , MoA extends CbMacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreCbMacros, ...rest: T): void; /** Skip this test. */ - (macro: OneOrMoreCbMacros<[], Context>): void + (macros: OneOrMoreCbMacros, ...rest: T): void; } export interface FailingInterface { @@ -632,13 +610,13 @@ export interface FailingInterface { * Declare a concurrent test that uses one or more macros. Additional arguments are passed to the macro. * The test is expected to fail. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** * Declare a concurrent test that uses one or more macros. The macro is responsible for generating a unique test title. * The test is expected to fail. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; only: OnlyInterface; skip: SkipInterface; @@ -655,12 +633,12 @@ export interface HookCbInterface { * Declare a hook that uses one or more macros. The macros must call `t.end()` when they're done. * Additional arguments are passed to the macro. */ - , MoA extends CbMacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreCbMacros, ...rest: T): void; /** * Declare a hook that uses one or more macros. The macros must call `t.end()` when they're done. */ - (macro: OneOrMoreCbMacros<[], Context>): void + (macros: OneOrMoreCbMacros, ...rest: T): void; skip: HookCbSkipInterface; } @@ -673,10 +651,10 @@ export interface HookCbSkipInterface { (title: string, implementation: CbImplementation): void; /** Skip this hook. */ - , MoA extends CbMacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreCbMacros, ...rest: T): void; /** Skip this hook. */ - (macro: OneOrMoreCbMacros<[], Context>): void + (macros: OneOrMoreCbMacros, ...rest: T): void; } export interface HookSkipInterface { @@ -687,10 +665,10 @@ export interface HookSkipInterface { (title: string, implementation: Implementation): void; /** Skip this hook. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** Skip this hook. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; } export interface OnlyInterface { @@ -701,13 +679,13 @@ export interface OnlyInterface { * Declare a test that uses one or more macros. Additional arguments are passed to the macro. * Only this test and others declared with `.only()` are run. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** * Declare a test that uses one or more macros. The macro is responsible for generating a unique test title. * Only this test and others declared with `.only()` are run. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; } export interface SerialInterface { @@ -715,12 +693,12 @@ export interface SerialInterface { (title: string, implementation: Implementation): void; /** Declare a serial test that uses one or more macros. Additional arguments are passed to the macro. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** * Declare a serial test that uses one or more macros. The macro is responsible for generating a unique test title. */ - (macro: OneOrMoreMacros<[], Context>): void + (macros: OneOrMoreMacros, ...rest: T): void; /** Declare a serial hook that is run once, after all tests have passed. */ after: AfterInterface; @@ -750,10 +728,10 @@ export interface SkipInterface { (title: string, implementation: Implementation): void; /** Skip this test. */ - , MoA extends MacroOrFirstArg>(titleOrMacro: ToM, macroOrArg: MoA, ...rest: RestArgs): void; + (title: string, macros: OneOrMoreMacros, ...rest: T): void; /** Skip this test. */ - (macro: OneOrMoreMacros<[], Context>): void + (title: string, macros: OneOrMoreMacros, ...rest: T): void; } export interface TodoDeclaration { @@ -804,33 +782,3 @@ export const todo: TodoDeclaration; /** Meta data associated with the current process. */ export const meta: MetaInterface; - -/* -Tail type from . - -MIT License - -Copyright (c) 2017 Thomas Crockett - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -/** Get all but the first element of a tuple. */ -export type Tail = - ((...args: T) => any) extends ((head: any, ...tail: infer R) => any) ? R : never; diff --git a/test/ts-types/macros.ts b/test/ts-types/macros.ts index 89d19e07d..ca0b4dab9 100644 --- a/test/ts-types/macros.ts +++ b/test/ts-types/macros.ts @@ -62,3 +62,14 @@ import test, {ExecutionContext, Macro} from '../..'; t.is(input.length, expected) }, 'bar', 3) } + +// Completely infer parameters +{ + test('has length 3', (t, input, expected) => { + t.is(input.length, expected); + }, 'foo', 3); + + test((t, input, expected) => { + t.is(input.length, expected) + }, 'foo', 3); +}