diff --git a/types/once/index.d.ts b/types/once/index.d.ts index 325edfab81..4561e28316 100644 --- a/types/once/index.d.ts +++ b/types/once/index.d.ts @@ -1,23 +1,48 @@ -// Type definitions for once v1.3.3 +// Type definitions for once 1.4 // Project: https://github.com/isaacs/once // Definitions by: Denis Sokolov +// BendingBender // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -interface SimpleFunction { - (...args: any[]): Result; +export = once; + +declare const once: Once; + +interface Once extends once.OnceFn { + proto(): void; + strict: once.OnceFn; } -interface OnceFunction extends SimpleFunction { - called: boolean; - value: Result; +declare namespace once { + interface OnceFn { + (f: () => R): (() => R) & FnProps; + (f: (t1: T1) => R): ((t1: T1) => R) & FnProps; + (f: (t1: T1, t2: T2) => R): ((t1: T1, t2: T2) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3) => R): ((t1: T1, t2: T2, t3: T3) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4) => R): ((t1: T1, t2: T2, t3: T3, t4: T4) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R): ((t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R): + ((t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7) => R): + ((t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8) => R): + ((t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8, t9: T9) => R): + ((t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8, t9: T9) => R) & FnProps; + (f: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8, t9: T9, t10: T10) => R): + ((t1: T1, t2: T2, t3: T3, t4: T4, t5: T5, t6: T6, t7: T7, t8: T8, t9: T9, t10: T10) => R) & FnProps; + (f: (...args: any[]) => R): ((...args: any[]) => R) & FnProps; + } + + interface FnProps { + called: boolean; + value: R | undefined; + } } -interface Once { - (f: SimpleFunction): OnceFunction; - proto: Function; -} - -declare module "once" { - var once: Once; - export default once; +declare global { + interface Function { + // tslint:disable-next-line ban-types + once(): Function & once.FnProps; + } } diff --git a/types/once/once-tests.ts b/types/once/once-tests.ts index a7931aced2..cfca6a8f6a 100644 --- a/types/once/once-tests.ts +++ b/types/once/once-tests.ts @@ -1,13 +1,53 @@ +import once = require('once'); - -import once from "once"; - +// $ExpectType (() => number) & FnProps once(() => 3); -once(() => 3)(); -let s = once(() => ({foo: 1}))(); -s.foo; +// $ExpectType ((t1: string) => number) & FnProps +once((t1: string) => 3); +// $ExpectType ((t1: string, t2: null) => number) & FnProps +once((t1: string, t2: null) => 3); +// $ExpectType ((t1: string, t2: null, t3: string) => number) & FnProps +once((t1: string, t2: null, t3: string) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null, t5: number) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null, t9: string) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null, t9: string) => 3); +// $ExpectType ((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null, t9: string, t10: null) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null, t9: string, t10: null) => 3); +// $ExpectType ((...args: any[]) => number) & FnProps +once((t1: string, t2: null, t3: string, t4: null, t5: number, t6: null, t7: string, t8: null, t9: string, t10: null, t11: string) => 3); + +once(() => 3)(); // $ExpectType number +once(() => ({foo: 1}))(); // $ExpectType { foo: number; } + +once(() => 3).called; // $ExpectType boolean +once(() => ({foo: 1})).value; // $ExpectType { foo: number; } | undefined once.proto(); -once(() => 3).called && true; -once(() => ({foo: 1})).value.foo; +once.strict(() => 3); // $ExpectType (() => number) & FnProps + +Function.prototype.once; // ExpectType () => Function & once.FnProps; +function fn() { + return 3; +} +fn.once(); // $ExpectType Function & FnProps + +function greet(name: string | null, cb: (greeting: string) => void) { + if (!name) cb('Hello anonymous'); + cb('Hello ' + name); +} +function log(msg: any) { +} +// this will print 'Hello anonymous' but the logical error will be missed +greet(null, once(log)); +// once.strict will print 'Hello anonymous' and throw an error when the callback will be called the second time +greet(null, once.strict(log)); diff --git a/types/once/tsconfig.json b/types/once/tsconfig.json index eb26ee77e7..4da17e3d3b 100644 --- a/types/once/tsconfig.json +++ b/types/once/tsconfig.json @@ -6,7 +6,7 @@ ], "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -19,4 +19,4 @@ "index.d.ts", "once-tests.ts" ] -} \ No newline at end of file +} diff --git a/types/once/tslint.json b/types/once/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/once/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }