-
-
Save Le0Michine/395417fbf050ec8d8aca0721e32b575a to your computer and use it in GitHub Desktop.
example demonstrating that in some cases inferred type could depend on the functions order in the code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Param { | |
name: string; | |
id?: number; | |
} | |
interface Result { | |
status: number; | |
} | |
type CallBack<T> = (result: T) => void; | |
interface OriginalApi1 { | |
fn(cb?: CallBack<Result>): string; | |
fn(p: Param, cb?: CallBack<Result>): string; | |
} | |
// Same as OriginalApi1 but with diffrent order of methods | |
interface OriginalApi2 { | |
fn(p: Param, cb?: CallBack<Result>): string; | |
fn(cb?: CallBack<Result>): string; | |
} | |
// Creates wrapper type which has methods with the same names as T returning Promise instead of using callbacks | |
type Wrapper<T> = { [K in keyof T]: T[K] extends (p: infer P1, cb?: (res: infer P2) => void) => infer R1 ? (p: P1) => Promise<P2> : never }; | |
// Same as Wrapper, supposed to return never if P1 is a Function | |
type WrapperIgnoringOverloads<T> = { [K in keyof T]: T[K] extends (p: infer P1, cb?: (res: infer P2) => void) => infer R1 ? P1 extends Function ? never : (p: P1) => Promise<P2> : never }; | |
let a: Wrapper<OriginalApi1>; | |
let b: Wrapper<OriginalApi2>; | |
a.fn({name: 'name'}); // OK, (property) fn: (p: Param) => Promise<Result> | |
b.fn({name: 'name'}); // Error, (property) fn: (p: CallBack<Result>) => Promise<Result> | |
let c: WrapperIgnoringOverloads<OriginalApi1>; | |
let d: WrapperIgnoringOverloads<OriginalApi2>; | |
c.fn({name: 'name'}); // OK, (property) fn: (p: Param) => Promise<Result> | |
d.fn({name: 'name'}); // Error, (property) fn: never |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment