From 55886a1e24d018aa7d5da61d9e5475653beb8e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 25 Sep 2024 22:21:41 +0200 Subject: [PATCH] Fixed incorrect `SignatureFlags.HasRestParameter` propagation when combining signatures (#58440) --- src/compiler/checker.ts | 17 +- ...gnatureCombiningRestParameters1.errors.txt | 29 +++ .../signatureCombiningRestParameters1.symbols | 62 +++++ .../signatureCombiningRestParameters1.types | 84 +++++++ .../signatureCombiningRestParameters2.symbols | 35 +++ .../signatureCombiningRestParameters2.types | 57 +++++ ...gnatureCombiningRestParameters3.errors.txt | 93 +++++++ .../signatureCombiningRestParameters3.symbols | 225 +++++++++++++++++ .../signatureCombiningRestParameters3.types | 226 ++++++++++++++++++ ...gnatureCombiningRestParameters4.errors.txt | 72 ++++++ .../signatureCombiningRestParameters4.symbols | 167 +++++++++++++ .../signatureCombiningRestParameters4.types | 170 +++++++++++++ ...gnatureCombiningRestParameters5.errors.txt | 34 +++ .../signatureCombiningRestParameters5.symbols | 69 ++++++ .../signatureCombiningRestParameters5.types | 121 ++++++++++ .../signatureCombiningRestParameters1.ts | 26 ++ .../signatureCombiningRestParameters2.ts | 13 + .../signatureCombiningRestParameters3.ts | 87 +++++++ .../signatureCombiningRestParameters4.ts | 66 +++++ .../signatureCombiningRestParameters5.ts | 27 +++ ...atureOptionalParameterFromIntersection1.ts | 12 + 21 files changed, 1689 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/signatureCombiningRestParameters1.errors.txt create mode 100644 tests/baselines/reference/signatureCombiningRestParameters1.symbols create mode 100644 tests/baselines/reference/signatureCombiningRestParameters1.types create mode 100644 tests/baselines/reference/signatureCombiningRestParameters2.symbols create mode 100644 tests/baselines/reference/signatureCombiningRestParameters2.types create mode 100644 tests/baselines/reference/signatureCombiningRestParameters3.errors.txt create mode 100644 tests/baselines/reference/signatureCombiningRestParameters3.symbols create mode 100644 tests/baselines/reference/signatureCombiningRestParameters3.types create mode 100644 tests/baselines/reference/signatureCombiningRestParameters4.errors.txt create mode 100644 tests/baselines/reference/signatureCombiningRestParameters4.symbols create mode 100644 tests/baselines/reference/signatureCombiningRestParameters4.types create mode 100644 tests/baselines/reference/signatureCombiningRestParameters5.errors.txt create mode 100644 tests/baselines/reference/signatureCombiningRestParameters5.symbols create mode 100644 tests/baselines/reference/signatureCombiningRestParameters5.types create mode 100644 tests/cases/compiler/signatureCombiningRestParameters1.ts create mode 100644 tests/cases/compiler/signatureCombiningRestParameters2.ts create mode 100644 tests/cases/compiler/signatureCombiningRestParameters3.ts create mode 100644 tests/cases/compiler/signatureCombiningRestParameters4.ts create mode 100644 tests/cases/compiler/signatureCombiningRestParameters5.ts create mode 100644 tests/cases/fourslash/quickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4016d82dafd..60d82a9ae6a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14032,8 +14032,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { paramMapper = createTypeMapper(right.typeParameters, left.typeParameters); // We just use the type parameter defaults from the first signature } + let flags = (left.flags | right.flags) & (SignatureFlags.PropagatingFlags & ~SignatureFlags.HasRestParameter); const declaration = left.declaration; const params = combineUnionParameters(left, right, paramMapper); + const lastParam = lastOrUndefined(params); + if (lastParam && getCheckFlags(lastParam) & CheckFlags.RestParameter) { + flags |= SignatureFlags.HasRestParameter; + } const thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter, paramMapper); const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount); const result = createSignature( @@ -14044,7 +14049,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgCount, - (left.flags | right.flags) & SignatureFlags.PropagatingFlags, + flags, ); result.compositeKind = TypeFlags.Union; result.compositeSignatures = concatenate(left.compositeKind !== TypeFlags.Intersection && left.compositeSignatures || [left], [right]); @@ -32545,12 +32550,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const paramSymbol = createSymbol( SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0), paramName || `arg${i}` as __String, + isRestParam ? CheckFlags.RestParameter : isOptional ? CheckFlags.OptionalParameter : 0, ); paramSymbol.links.type = isRestParam ? createArrayType(unionParamType) : unionParamType; params[i] = paramSymbol; } if (needsExtraRestElement) { - const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String); + const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String, CheckFlags.RestParameter); restParamSymbol.links.type = createArrayType(getTypeAtPosition(shorter, longestCount)); if (shorter === right) { restParamSymbol.links.type = instantiateType(restParamSymbol.links.type, mapper); @@ -32567,8 +32573,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { paramMapper = createTypeMapper(right.typeParameters, left.typeParameters); // We just use the type parameter defaults from the first signature } + let flags = (left.flags | right.flags) & (SignatureFlags.PropagatingFlags & ~SignatureFlags.HasRestParameter); const declaration = left.declaration; const params = combineIntersectionParameters(left, right, paramMapper); + const lastParam = lastOrUndefined(params); + if (lastParam && getCheckFlags(lastParam) & CheckFlags.RestParameter) { + flags |= SignatureFlags.HasRestParameter; + } const thisParam = combineIntersectionThisParam(left.thisParameter, right.thisParameter, paramMapper); const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount); const result = createSignature( @@ -32579,7 +32590,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgCount, - (left.flags | right.flags) & SignatureFlags.PropagatingFlags, + flags, ); result.compositeKind = TypeFlags.Intersection; result.compositeSignatures = concatenate(left.compositeKind === TypeFlags.Intersection && left.compositeSignatures || [left], [right]); diff --git a/tests/baselines/reference/signatureCombiningRestParameters1.errors.txt b/tests/baselines/reference/signatureCombiningRestParameters1.errors.txt new file mode 100644 index 00000000000..de090b86ff0 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters1.errors.txt @@ -0,0 +1,29 @@ +signatureCombiningRestParameters1.ts(17,6): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. + + +==== signatureCombiningRestParameters1.ts (1 errors) ==== + // https://github.com/microsoft/TypeScript/issues/58371 + + type T1 = "A" | "B"; + + type T2 = { + C: [string]; + D: [number]; + }; + + declare const map: { + [K in T1 | keyof T2]: (...args: K extends keyof T2 ? T2[K] : []) => unknown; + }; + + declare const args: any; + + for (const [key, fn] of Object.entries(map)) { + fn(...args); + ~~~~~~~ +!!! error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. + } + + const test2: ((a: number, ...args: []) => void) & + ((b: string) => void) & + ((c: boolean) => void) = (arg) => {}; + \ No newline at end of file diff --git a/tests/baselines/reference/signatureCombiningRestParameters1.symbols b/tests/baselines/reference/signatureCombiningRestParameters1.symbols new file mode 100644 index 00000000000..17a3887f6d8 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters1.symbols @@ -0,0 +1,62 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters1.ts] //// + +=== signatureCombiningRestParameters1.ts === +// https://github.com/microsoft/TypeScript/issues/58371 + +type T1 = "A" | "B"; +>T1 : Symbol(T1, Decl(signatureCombiningRestParameters1.ts, 0, 0)) + +type T2 = { +>T2 : Symbol(T2, Decl(signatureCombiningRestParameters1.ts, 2, 20)) + + C: [string]; +>C : Symbol(C, Decl(signatureCombiningRestParameters1.ts, 4, 11)) + + D: [number]; +>D : Symbol(D, Decl(signatureCombiningRestParameters1.ts, 5, 14)) + +}; + +declare const map: { +>map : Symbol(map, Decl(signatureCombiningRestParameters1.ts, 9, 13)) + + [K in T1 | keyof T2]: (...args: K extends keyof T2 ? T2[K] : []) => unknown; +>K : Symbol(K, Decl(signatureCombiningRestParameters1.ts, 10, 3)) +>T1 : Symbol(T1, Decl(signatureCombiningRestParameters1.ts, 0, 0)) +>T2 : Symbol(T2, Decl(signatureCombiningRestParameters1.ts, 2, 20)) +>args : Symbol(args, Decl(signatureCombiningRestParameters1.ts, 10, 25)) +>K : Symbol(K, Decl(signatureCombiningRestParameters1.ts, 10, 3)) +>T2 : Symbol(T2, Decl(signatureCombiningRestParameters1.ts, 2, 20)) +>T2 : Symbol(T2, Decl(signatureCombiningRestParameters1.ts, 2, 20)) +>K : Symbol(K, Decl(signatureCombiningRestParameters1.ts, 10, 3)) + +}; + +declare const args: any; +>args : Symbol(args, Decl(signatureCombiningRestParameters1.ts, 13, 13)) + +for (const [key, fn] of Object.entries(map)) { +>key : Symbol(key, Decl(signatureCombiningRestParameters1.ts, 15, 12)) +>fn : Symbol(fn, Decl(signatureCombiningRestParameters1.ts, 15, 16)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>map : Symbol(map, Decl(signatureCombiningRestParameters1.ts, 9, 13)) + + fn(...args); +>fn : Symbol(fn, Decl(signatureCombiningRestParameters1.ts, 15, 16)) +>args : Symbol(args, Decl(signatureCombiningRestParameters1.ts, 13, 13)) +} + +const test2: ((a: number, ...args: []) => void) & +>test2 : Symbol(test2, Decl(signatureCombiningRestParameters1.ts, 19, 5)) +>a : Symbol(a, Decl(signatureCombiningRestParameters1.ts, 19, 15)) +>args : Symbol(args, Decl(signatureCombiningRestParameters1.ts, 19, 25)) + + ((b: string) => void) & +>b : Symbol(b, Decl(signatureCombiningRestParameters1.ts, 20, 4)) + + ((c: boolean) => void) = (arg) => {}; +>c : Symbol(c, Decl(signatureCombiningRestParameters1.ts, 21, 4)) +>arg : Symbol(arg, Decl(signatureCombiningRestParameters1.ts, 21, 28)) + diff --git a/tests/baselines/reference/signatureCombiningRestParameters1.types b/tests/baselines/reference/signatureCombiningRestParameters1.types new file mode 100644 index 00000000000..674d561e55d --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters1.types @@ -0,0 +1,84 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters1.ts] //// + +=== signatureCombiningRestParameters1.ts === +// https://github.com/microsoft/TypeScript/issues/58371 + +type T1 = "A" | "B"; +>T1 : T1 +> : ^^ + +type T2 = { +>T2 : T2 +> : ^^ + + C: [string]; +>C : [string] +> : ^^^^^^^^ + + D: [number]; +>D : [number] +> : ^^^^^^^^ + +}; + +declare const map: { +>map : { A: () => unknown; B: () => unknown; C: (args_0: string) => unknown; D: (args_0: number) => unknown; } +> : ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ + + [K in T1 | keyof T2]: (...args: K extends keyof T2 ? T2[K] : []) => unknown; +>args : K extends keyof T2 ? T2[K] : [] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}; + +declare const args: any; +>args : any +> : ^^^ + +for (const [key, fn] of Object.entries(map)) { +>key : string +> : ^^^^^^ +>fn : (() => unknown) | (() => unknown) | ((args_0: string) => unknown) | ((args_0: number) => unknown) +> : ^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^ +>Object.entries(map) : [string, (() => unknown) | (() => unknown) | ((args_0: string) => unknown) | ((args_0: number) => unknown)][] +> : ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^ +>Object : ObjectConstructor +> : ^^^^^^^^^^^^^^^^^ +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^^ ^^^ +>map : { A: () => unknown; B: () => unknown; C: (args_0: string) => unknown; D: (args_0: number) => unknown; } +> : ^^^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ + + fn(...args); +>fn(...args) : unknown +> : ^^^^^^^ +>fn : (() => unknown) | (() => unknown) | ((args_0: string) => unknown) | ((args_0: number) => unknown) +> : ^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^ +>...args : any +> : ^^^ +>args : any +> : ^^^ +} + +const test2: ((a: number, ...args: []) => void) & +>test2 : ((a: number) => void) & ((b: string) => void) & ((c: boolean) => void) +> : ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^ +>a : number +> : ^^^^^^ +>args : [] +> : ^^ + + ((b: string) => void) & +>b : string +> : ^^^^^^ + + ((c: boolean) => void) = (arg) => {}; +>c : boolean +> : ^^^^^^^ +>(arg) => {} : (arg: string | number | boolean) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>arg : string | number | boolean +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/baselines/reference/signatureCombiningRestParameters2.symbols b/tests/baselines/reference/signatureCombiningRestParameters2.symbols new file mode 100644 index 00000000000..894c556f5a4 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters2.symbols @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters2.ts] //// + +=== signatureCombiningRestParameters2.ts === +interface Console { +>Console : Symbol(Console, Decl(lib.dom.d.ts, --, --), Decl(signatureCombiningRestParameters2.ts, 0, 0)) + + log(message?: any, ...optionalParams: any[]): void; +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --), Decl(signatureCombiningRestParameters2.ts, 0, 19)) +>message : Symbol(message, Decl(signatureCombiningRestParameters2.ts, 1, 6)) +>optionalParams : Symbol(optionalParams, Decl(signatureCombiningRestParameters2.ts, 1, 20)) +} + +let logs: string[] = []; +>logs : Symbol(logs, Decl(signatureCombiningRestParameters2.ts, 4, 3)) + +let originalLog: typeof console.log; +>originalLog : Symbol(originalLog, Decl(signatureCombiningRestParameters2.ts, 5, 3)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --), Decl(signatureCombiningRestParameters2.ts, 0, 19)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --), Decl(signatureCombiningRestParameters2.ts, 0, 19)) + +console.log = (...args) => { +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --), Decl(signatureCombiningRestParameters2.ts, 0, 19)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --), Decl(signatureCombiningRestParameters2.ts, 0, 19)) +>args : Symbol(args, Decl(signatureCombiningRestParameters2.ts, 6, 15)) + + logs.push(...args); +>logs.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>logs : Symbol(logs, Decl(signatureCombiningRestParameters2.ts, 4, 3)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(signatureCombiningRestParameters2.ts, 6, 15)) + +}; + diff --git a/tests/baselines/reference/signatureCombiningRestParameters2.types b/tests/baselines/reference/signatureCombiningRestParameters2.types new file mode 100644 index 00000000000..8d8a820d900 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters2.types @@ -0,0 +1,57 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters2.ts] //// + +=== signatureCombiningRestParameters2.ts === +interface Console { + log(message?: any, ...optionalParams: any[]): void; +>log : { (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; } +> : ^^^^^^ ^^ ^^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^ +>message : any +>optionalParams : any[] +> : ^^^^^ +} + +let logs: string[] = []; +>logs : string[] +> : ^^^^^^^^ +>[] : never[] +> : ^^^^^^^ + +let originalLog: typeof console.log; +>originalLog : { (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; } +> : ^^^^^^ ^^ ^^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^ +>console.log : { (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; } +> : ^^^^^^ ^^ ^^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^ +>console : Console +> : ^^^^^^^ +>log : { (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; } +> : ^^^^^^ ^^ ^^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^ + +console.log = (...args) => { +>console.log = (...args) => { logs.push(...args);} : (args_0?: any, ...args: any[]) => void +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>console.log : { (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; } +> : ^^^^^^ ^^ ^^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^ +>console : Console +> : ^^^^^^^ +>log : { (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; } +> : ^^^^^^ ^^ ^^^ ^^^ ^^^ ^^^^^ ^^ ^^^ ^^^ +>(...args) => { logs.push(...args);} : (args_0?: any, ...args: any[]) => void +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>args : [any?, ...any[]] +> : ^^^^^^^^^^^^^^^^ + + logs.push(...args); +>logs.push(...args) : number +> : ^^^^^^ +>logs.push : (...items: string[]) => number +> : ^^^^ ^^^^^^^^^^^^^^^ +>logs : string[] +> : ^^^^^^^^ +>push : (...items: string[]) => number +> : ^^^^ ^^^^^^^^^^^^^^^ +>...args : any +>args : [any?, ...any[]] +> : ^^^^^^^^^^^^^^^^ + +}; + diff --git a/tests/baselines/reference/signatureCombiningRestParameters3.errors.txt b/tests/baselines/reference/signatureCombiningRestParameters3.errors.txt new file mode 100644 index 00000000000..57b70de8618 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters3.errors.txt @@ -0,0 +1,93 @@ +signatureCombiningRestParameters3.ts(81,20): error TS2345: Argument of type 'Mark' is not assignable to parameter of type 'Mark & Node'. + Type 'Mark' is missing the following properties from type 'Node': type, name, parent, child + + +==== signatureCombiningRestParameters3.ts (1 errors) ==== + interface ExtensionConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Mark, + ) => Record) + | null; + } + + declare class Extension { + type: string; + name: string; + parent: Extension | null; + child: Extension | null; + options: Options; + config: ExtensionConfig; + } + + declare class Node { + type: string; + name: string; + parent: Node | null; + child: Node | null; + options: Options; + } + + interface NodeConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Node, + ) => Record) + | null; + } + + declare class Mark { + options: Options; + config: MarkConfig; + } + + interface MarkConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Mark, + ) => Record) + | null; + } + + type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig; + type AnyExtension = Extension | Node | Mark; + + declare const e: AnyExtension; + + type RemoveThis = T extends (...args: any) => any + ? (...args: Parameters) => ReturnType + : T; + + declare function getExtensionField( + extension: AnyExtension, + field: string, + ): RemoveThis; + + const extendMarkSchema = getExtensionField( + e, + "extendMarkSchema", + ); + + declare const extension: Mark; + + if (extendMarkSchema) { + extendMarkSchema(extension); // error + ~~~~~~~~~ +!!! error TS2345: Argument of type 'Mark' is not assignable to parameter of type 'Mark & Node'. +!!! error TS2345: Type 'Mark' is missing the following properties from type 'Node': type, name, parent, child + } + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/signatureCombiningRestParameters3.symbols b/tests/baselines/reference/signatureCombiningRestParameters3.symbols new file mode 100644 index 00000000000..b0f98f13985 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters3.symbols @@ -0,0 +1,225 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters3.ts] //// + +=== signatureCombiningRestParameters3.ts === +interface ExtensionConfig { +>ExtensionConfig : Symbol(ExtensionConfig, Decl(signatureCombiningRestParameters3.ts, 0, 0)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 0, 26)) + + extendMarkSchema?: +>extendMarkSchema : Symbol(ExtensionConfig.extendMarkSchema, Decl(signatureCombiningRestParameters3.ts, 0, 42)) + + | (( + this: { +>this : Symbol(this, Decl(signatureCombiningRestParameters3.ts, 2, 8)) + + name: string; +>name : Symbol(name, Decl(signatureCombiningRestParameters3.ts, 3, 15)) + + options: Options; +>options : Symbol(options, Decl(signatureCombiningRestParameters3.ts, 4, 23)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 0, 26)) + + }, + extension: Mark, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters3.ts, 6, 10)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters3.ts, 39, 1)) + + ) => Record) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + | null; +} + +declare class Extension { +>Extension : Symbol(Extension, Decl(signatureCombiningRestParameters3.ts, 10, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 12, 24)) + + type: string; +>type : Symbol(Extension.type, Decl(signatureCombiningRestParameters3.ts, 12, 40)) + + name: string; +>name : Symbol(Extension.name, Decl(signatureCombiningRestParameters3.ts, 13, 15)) + + parent: Extension | null; +>parent : Symbol(Extension.parent, Decl(signatureCombiningRestParameters3.ts, 14, 15)) +>Extension : Symbol(Extension, Decl(signatureCombiningRestParameters3.ts, 10, 1)) + + child: Extension | null; +>child : Symbol(Extension.child, Decl(signatureCombiningRestParameters3.ts, 15, 27)) +>Extension : Symbol(Extension, Decl(signatureCombiningRestParameters3.ts, 10, 1)) + + options: Options; +>options : Symbol(Extension.options, Decl(signatureCombiningRestParameters3.ts, 16, 26)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 12, 24)) + + config: ExtensionConfig; +>config : Symbol(Extension.config, Decl(signatureCombiningRestParameters3.ts, 17, 19)) +>ExtensionConfig : Symbol(ExtensionConfig, Decl(signatureCombiningRestParameters3.ts, 0, 0)) +} + +declare class Node { +>Node : Symbol(Node, Decl(signatureCombiningRestParameters3.ts, 19, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 21, 19)) + + type: string; +>type : Symbol(Node.type, Decl(signatureCombiningRestParameters3.ts, 21, 35)) + + name: string; +>name : Symbol(Node.name, Decl(signatureCombiningRestParameters3.ts, 22, 15)) + + parent: Node | null; +>parent : Symbol(Node.parent, Decl(signatureCombiningRestParameters3.ts, 23, 15)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters3.ts, 19, 1)) + + child: Node | null; +>child : Symbol(Node.child, Decl(signatureCombiningRestParameters3.ts, 24, 22)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters3.ts, 19, 1)) + + options: Options; +>options : Symbol(Node.options, Decl(signatureCombiningRestParameters3.ts, 25, 21)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 21, 19)) +} + +interface NodeConfig { +>NodeConfig : Symbol(NodeConfig, Decl(signatureCombiningRestParameters3.ts, 27, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 29, 21)) + + extendMarkSchema?: +>extendMarkSchema : Symbol(NodeConfig.extendMarkSchema, Decl(signatureCombiningRestParameters3.ts, 29, 37)) + + | (( + this: { +>this : Symbol(this, Decl(signatureCombiningRestParameters3.ts, 31, 8)) + + name: string; +>name : Symbol(name, Decl(signatureCombiningRestParameters3.ts, 32, 15)) + + options: Options; +>options : Symbol(options, Decl(signatureCombiningRestParameters3.ts, 33, 23)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 29, 21)) + + }, + extension: Node, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters3.ts, 35, 10)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters3.ts, 19, 1)) + + ) => Record) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + | null; +} + +declare class Mark { +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters3.ts, 39, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 41, 19)) + + options: Options; +>options : Symbol(Mark.options, Decl(signatureCombiningRestParameters3.ts, 41, 35)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 41, 19)) + + config: MarkConfig; +>config : Symbol(Mark.config, Decl(signatureCombiningRestParameters3.ts, 42, 19)) +>MarkConfig : Symbol(MarkConfig, Decl(signatureCombiningRestParameters3.ts, 44, 1)) +} + +interface MarkConfig { +>MarkConfig : Symbol(MarkConfig, Decl(signatureCombiningRestParameters3.ts, 44, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 46, 21)) + + extendMarkSchema?: +>extendMarkSchema : Symbol(MarkConfig.extendMarkSchema, Decl(signatureCombiningRestParameters3.ts, 46, 37)) + + | (( + this: { +>this : Symbol(this, Decl(signatureCombiningRestParameters3.ts, 48, 8)) + + name: string; +>name : Symbol(name, Decl(signatureCombiningRestParameters3.ts, 49, 15)) + + options: Options; +>options : Symbol(options, Decl(signatureCombiningRestParameters3.ts, 50, 23)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters3.ts, 46, 21)) + + }, + extension: Mark, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters3.ts, 52, 10)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters3.ts, 39, 1)) + + ) => Record) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + | null; +} + +type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig; +>AnyConfig : Symbol(AnyConfig, Decl(signatureCombiningRestParameters3.ts, 56, 1)) +>ExtensionConfig : Symbol(ExtensionConfig, Decl(signatureCombiningRestParameters3.ts, 0, 0)) +>NodeConfig : Symbol(NodeConfig, Decl(signatureCombiningRestParameters3.ts, 27, 1)) +>MarkConfig : Symbol(MarkConfig, Decl(signatureCombiningRestParameters3.ts, 44, 1)) + +type AnyExtension = Extension | Node | Mark; +>AnyExtension : Symbol(AnyExtension, Decl(signatureCombiningRestParameters3.ts, 58, 59)) +>Extension : Symbol(Extension, Decl(signatureCombiningRestParameters3.ts, 10, 1)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters3.ts, 19, 1)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters3.ts, 39, 1)) + +declare const e: AnyExtension; +>e : Symbol(e, Decl(signatureCombiningRestParameters3.ts, 61, 13)) +>AnyExtension : Symbol(AnyExtension, Decl(signatureCombiningRestParameters3.ts, 58, 59)) + +type RemoveThis = T extends (...args: any) => any +>RemoveThis : Symbol(RemoveThis, Decl(signatureCombiningRestParameters3.ts, 61, 30)) +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 63, 16)) +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 63, 16)) +>args : Symbol(args, Decl(signatureCombiningRestParameters3.ts, 63, 32)) + + ? (...args: Parameters) => ReturnType +>args : Symbol(args, Decl(signatureCombiningRestParameters3.ts, 64, 5)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 63, 16)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 63, 16)) + + : T; +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 63, 16)) + +declare function getExtensionField( +>getExtensionField : Symbol(getExtensionField, Decl(signatureCombiningRestParameters3.ts, 65, 6)) +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 67, 35)) + + extension: AnyExtension, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters3.ts, 67, 44)) +>AnyExtension : Symbol(AnyExtension, Decl(signatureCombiningRestParameters3.ts, 58, 59)) + + field: string, +>field : Symbol(field, Decl(signatureCombiningRestParameters3.ts, 68, 26)) + +): RemoveThis; +>RemoveThis : Symbol(RemoveThis, Decl(signatureCombiningRestParameters3.ts, 61, 30)) +>T : Symbol(T, Decl(signatureCombiningRestParameters3.ts, 67, 35)) + +const extendMarkSchema = getExtensionField( +>extendMarkSchema : Symbol(extendMarkSchema, Decl(signatureCombiningRestParameters3.ts, 72, 5)) +>getExtensionField : Symbol(getExtensionField, Decl(signatureCombiningRestParameters3.ts, 65, 6)) +>AnyConfig : Symbol(AnyConfig, Decl(signatureCombiningRestParameters3.ts, 56, 1)) + + e, +>e : Symbol(e, Decl(signatureCombiningRestParameters3.ts, 61, 13)) + + "extendMarkSchema", +); + +declare const extension: Mark; +>extension : Symbol(extension, Decl(signatureCombiningRestParameters3.ts, 77, 13)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters3.ts, 39, 1)) + +if (extendMarkSchema) { +>extendMarkSchema : Symbol(extendMarkSchema, Decl(signatureCombiningRestParameters3.ts, 72, 5)) + + extendMarkSchema(extension); // error +>extendMarkSchema : Symbol(extendMarkSchema, Decl(signatureCombiningRestParameters3.ts, 72, 5)) +>extension : Symbol(extension, Decl(signatureCombiningRestParameters3.ts, 77, 13)) +} + +export {}; + diff --git a/tests/baselines/reference/signatureCombiningRestParameters3.types b/tests/baselines/reference/signatureCombiningRestParameters3.types new file mode 100644 index 00000000000..72600d20bf3 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters3.types @@ -0,0 +1,226 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters3.ts] //// + +=== signatureCombiningRestParameters3.ts === +interface ExtensionConfig { + extendMarkSchema?: +>extendMarkSchema : ((this: { name: string; options: Options; }, extension: Mark) => Record) | null | undefined +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + | (( + this: { +>this : { name: string; options: Options; } +> : ^^^^^^^^ ^^^^^^^^^^^ ^^^ + + name: string; +>name : string +> : ^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + }, + extension: Mark, +>extension : Mark +> : ^^^^^^^^^ + + ) => Record) + | null; +} + +declare class Extension { +>Extension : Extension +> : ^^^^^^^^^^^^^^^^^^ + + type: string; +>type : string +> : ^^^^^^ + + name: string; +>name : string +> : ^^^^^^ + + parent: Extension | null; +>parent : Extension | null +> : ^^^^^^^^^^^^^^^^^^^^^ + + child: Extension | null; +>child : Extension | null +> : ^^^^^^^^^^^^^^^^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + config: ExtensionConfig; +>config : ExtensionConfig +> : ^^^^^^^^^^^^^^^^^^^^ +} + +declare class Node { +>Node : Node +> : ^^^^^^^^^^^^^ + + type: string; +>type : string +> : ^^^^^^ + + name: string; +>name : string +> : ^^^^^^ + + parent: Node | null; +>parent : Node | null +> : ^^^^^^^^^^^^^^^^ + + child: Node | null; +>child : Node | null +> : ^^^^^^^^^^^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ +} + +interface NodeConfig { + extendMarkSchema?: +>extendMarkSchema : ((this: { name: string; options: Options; }, extension: Node) => Record) | null | undefined +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + | (( + this: { +>this : { name: string; options: Options; } +> : ^^^^^^^^ ^^^^^^^^^^^ ^^^ + + name: string; +>name : string +> : ^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + }, + extension: Node, +>extension : Node +> : ^^^^^^^^^ + + ) => Record) + | null; +} + +declare class Mark { +>Mark : Mark +> : ^^^^^^^^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + config: MarkConfig; +>config : MarkConfig +> : ^^^^^^^^^^^^^^^ +} + +interface MarkConfig { + extendMarkSchema?: +>extendMarkSchema : ((this: { name: string; options: Options; }, extension: Mark) => Record) | null | undefined +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + | (( + this: { +>this : { name: string; options: Options; } +> : ^^^^^^^^ ^^^^^^^^^^^ ^^^ + + name: string; +>name : string +> : ^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + }, + extension: Mark, +>extension : Mark +> : ^^^^^^^^^ + + ) => Record) + | null; +} + +type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig; +>AnyConfig : AnyConfig +> : ^^^^^^^^^ + +type AnyExtension = Extension | Node | Mark; +>AnyExtension : AnyExtension +> : ^^^^^^^^^^^^ + +declare const e: AnyExtension; +>e : AnyExtension +> : ^^^^^^^^^^^^ + +type RemoveThis = T extends (...args: any) => any +>RemoveThis : RemoveThis +> : ^^^^^^^^^^^^^ +>args : any +> : ^^^ + + ? (...args: Parameters) => ReturnType +>args : Parameters +> : ^^^^^^^^^^^^^ + + : T; + +declare function getExtensionField( +>getExtensionField : (extension: AnyExtension, field: string) => RemoveThis +> : ^ ^^^^^^^^ ^^ ^^ ^^ ^^^^^ + + extension: AnyExtension, +>extension : AnyExtension +> : ^^^^^^^^^^^^ + + field: string, +>field : string +> : ^^^^^^ + +): RemoveThis; + +const extendMarkSchema = getExtensionField( +>extendMarkSchema : ((extension: Mark) => Record) | ((extension: Node) => Record) | ((extension: Mark) => Record) | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>getExtensionField( e, "extendMarkSchema",) : ((extension: Mark) => Record) | ((extension: Node) => Record) | ((extension: Mark) => Record) | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>getExtensionField : (extension: AnyExtension, field: string) => RemoveThis +> : ^ ^^^^^^^^ ^^ ^^ ^^ ^^^^^ + + e, +>e : AnyExtension +> : ^^^^^^^^^^^^ + + "extendMarkSchema", +>"extendMarkSchema" : "extendMarkSchema" +> : ^^^^^^^^^^^^^^^^^^ + +); + +declare const extension: Mark; +>extension : Mark +> : ^^^^^^^^^ + +if (extendMarkSchema) { +>extendMarkSchema : ((extension: Mark) => Record) | ((extension: Node) => Record) | ((extension: Mark) => Record) | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + extendMarkSchema(extension); // error +>extendMarkSchema(extension) : Record +> : ^^^^^^^^^^^^^^^^^^^ +>extendMarkSchema : ((extension: Mark) => Record) | ((extension: Node) => Record) | ((extension: Mark) => Record) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>extension : Mark +> : ^^^^^^^^^ +} + +export {}; + diff --git a/tests/baselines/reference/signatureCombiningRestParameters4.errors.txt b/tests/baselines/reference/signatureCombiningRestParameters4.errors.txt new file mode 100644 index 00000000000..03c6aa38c4a --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters4.errors.txt @@ -0,0 +1,72 @@ +signatureCombiningRestParameters4.ts(60,20): error TS2345: Argument of type 'Mark' is not assignable to parameter of type 'Node & Mark'. + Type 'Mark' is missing the following properties from type 'Node': type, name, parent, child + + +==== signatureCombiningRestParameters4.ts (1 errors) ==== + declare class Node { + type: string; + name: string; + parent: Node | null; + child: Node | null; + options: Options; + } + + interface NodeConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Node, + ) => Record) + | null; + } + + declare class Mark { + options: Options; + config: MarkConfig; + } + + interface MarkConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Mark, + ) => Record) + | null; + } + + type AnyConfig = NodeConfig | MarkConfig; + type AnyExtension = Node | Mark; + + declare const e: AnyExtension; + + type RemoveThis = T extends (...args: any) => any + ? (...args: Parameters) => ReturnType + : T; + + declare function getExtensionField( + extension: AnyExtension, + field: string, + ): RemoveThis; + + const extendMarkSchema = getExtensionField( + e, + "extendMarkSchema", + ); + + declare const extension: Mark; + + if (extendMarkSchema) { + extendMarkSchema(extension); // error + ~~~~~~~~~ +!!! error TS2345: Argument of type 'Mark' is not assignable to parameter of type 'Node & Mark'. +!!! error TS2345: Type 'Mark' is missing the following properties from type 'Node': type, name, parent, child + } + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/signatureCombiningRestParameters4.symbols b/tests/baselines/reference/signatureCombiningRestParameters4.symbols new file mode 100644 index 00000000000..3a10f9b0090 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters4.symbols @@ -0,0 +1,167 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters4.ts] //// + +=== signatureCombiningRestParameters4.ts === +declare class Node { +>Node : Symbol(Node, Decl(signatureCombiningRestParameters4.ts, 0, 0)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 0, 19)) + + type: string; +>type : Symbol(Node.type, Decl(signatureCombiningRestParameters4.ts, 0, 35)) + + name: string; +>name : Symbol(Node.name, Decl(signatureCombiningRestParameters4.ts, 1, 15)) + + parent: Node | null; +>parent : Symbol(Node.parent, Decl(signatureCombiningRestParameters4.ts, 2, 15)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters4.ts, 0, 0)) + + child: Node | null; +>child : Symbol(Node.child, Decl(signatureCombiningRestParameters4.ts, 3, 22)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters4.ts, 0, 0)) + + options: Options; +>options : Symbol(Node.options, Decl(signatureCombiningRestParameters4.ts, 4, 21)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 0, 19)) +} + +interface NodeConfig { +>NodeConfig : Symbol(NodeConfig, Decl(signatureCombiningRestParameters4.ts, 6, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 8, 21)) + + extendMarkSchema?: +>extendMarkSchema : Symbol(NodeConfig.extendMarkSchema, Decl(signatureCombiningRestParameters4.ts, 8, 37)) + + | (( + this: { +>this : Symbol(this, Decl(signatureCombiningRestParameters4.ts, 10, 8)) + + name: string; +>name : Symbol(name, Decl(signatureCombiningRestParameters4.ts, 11, 15)) + + options: Options; +>options : Symbol(options, Decl(signatureCombiningRestParameters4.ts, 12, 23)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 8, 21)) + + }, + extension: Node, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters4.ts, 14, 10)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters4.ts, 0, 0)) + + ) => Record) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + | null; +} + +declare class Mark { +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters4.ts, 18, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 20, 19)) + + options: Options; +>options : Symbol(Mark.options, Decl(signatureCombiningRestParameters4.ts, 20, 35)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 20, 19)) + + config: MarkConfig; +>config : Symbol(Mark.config, Decl(signatureCombiningRestParameters4.ts, 21, 19)) +>MarkConfig : Symbol(MarkConfig, Decl(signatureCombiningRestParameters4.ts, 23, 1)) +} + +interface MarkConfig { +>MarkConfig : Symbol(MarkConfig, Decl(signatureCombiningRestParameters4.ts, 23, 1)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 25, 21)) + + extendMarkSchema?: +>extendMarkSchema : Symbol(MarkConfig.extendMarkSchema, Decl(signatureCombiningRestParameters4.ts, 25, 37)) + + | (( + this: { +>this : Symbol(this, Decl(signatureCombiningRestParameters4.ts, 27, 8)) + + name: string; +>name : Symbol(name, Decl(signatureCombiningRestParameters4.ts, 28, 15)) + + options: Options; +>options : Symbol(options, Decl(signatureCombiningRestParameters4.ts, 29, 23)) +>Options : Symbol(Options, Decl(signatureCombiningRestParameters4.ts, 25, 21)) + + }, + extension: Mark, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters4.ts, 31, 10)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters4.ts, 18, 1)) + + ) => Record) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + | null; +} + +type AnyConfig = NodeConfig | MarkConfig; +>AnyConfig : Symbol(AnyConfig, Decl(signatureCombiningRestParameters4.ts, 35, 1)) +>NodeConfig : Symbol(NodeConfig, Decl(signatureCombiningRestParameters4.ts, 6, 1)) +>MarkConfig : Symbol(MarkConfig, Decl(signatureCombiningRestParameters4.ts, 23, 1)) + +type AnyExtension = Node | Mark; +>AnyExtension : Symbol(AnyExtension, Decl(signatureCombiningRestParameters4.ts, 37, 41)) +>Node : Symbol(Node, Decl(signatureCombiningRestParameters4.ts, 0, 0)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters4.ts, 18, 1)) + +declare const e: AnyExtension; +>e : Symbol(e, Decl(signatureCombiningRestParameters4.ts, 40, 13)) +>AnyExtension : Symbol(AnyExtension, Decl(signatureCombiningRestParameters4.ts, 37, 41)) + +type RemoveThis = T extends (...args: any) => any +>RemoveThis : Symbol(RemoveThis, Decl(signatureCombiningRestParameters4.ts, 40, 30)) +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 42, 16)) +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 42, 16)) +>args : Symbol(args, Decl(signatureCombiningRestParameters4.ts, 42, 32)) + + ? (...args: Parameters) => ReturnType +>args : Symbol(args, Decl(signatureCombiningRestParameters4.ts, 43, 5)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 42, 16)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 42, 16)) + + : T; +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 42, 16)) + +declare function getExtensionField( +>getExtensionField : Symbol(getExtensionField, Decl(signatureCombiningRestParameters4.ts, 44, 6)) +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 46, 35)) + + extension: AnyExtension, +>extension : Symbol(extension, Decl(signatureCombiningRestParameters4.ts, 46, 44)) +>AnyExtension : Symbol(AnyExtension, Decl(signatureCombiningRestParameters4.ts, 37, 41)) + + field: string, +>field : Symbol(field, Decl(signatureCombiningRestParameters4.ts, 47, 26)) + +): RemoveThis; +>RemoveThis : Symbol(RemoveThis, Decl(signatureCombiningRestParameters4.ts, 40, 30)) +>T : Symbol(T, Decl(signatureCombiningRestParameters4.ts, 46, 35)) + +const extendMarkSchema = getExtensionField( +>extendMarkSchema : Symbol(extendMarkSchema, Decl(signatureCombiningRestParameters4.ts, 51, 5)) +>getExtensionField : Symbol(getExtensionField, Decl(signatureCombiningRestParameters4.ts, 44, 6)) +>AnyConfig : Symbol(AnyConfig, Decl(signatureCombiningRestParameters4.ts, 35, 1)) + + e, +>e : Symbol(e, Decl(signatureCombiningRestParameters4.ts, 40, 13)) + + "extendMarkSchema", +); + +declare const extension: Mark; +>extension : Symbol(extension, Decl(signatureCombiningRestParameters4.ts, 56, 13)) +>Mark : Symbol(Mark, Decl(signatureCombiningRestParameters4.ts, 18, 1)) + +if (extendMarkSchema) { +>extendMarkSchema : Symbol(extendMarkSchema, Decl(signatureCombiningRestParameters4.ts, 51, 5)) + + extendMarkSchema(extension); // error +>extendMarkSchema : Symbol(extendMarkSchema, Decl(signatureCombiningRestParameters4.ts, 51, 5)) +>extension : Symbol(extension, Decl(signatureCombiningRestParameters4.ts, 56, 13)) +} + +export {}; + diff --git a/tests/baselines/reference/signatureCombiningRestParameters4.types b/tests/baselines/reference/signatureCombiningRestParameters4.types new file mode 100644 index 00000000000..04e9da6228e --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters4.types @@ -0,0 +1,170 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters4.ts] //// + +=== signatureCombiningRestParameters4.ts === +declare class Node { +>Node : Node +> : ^^^^^^^^^^^^^ + + type: string; +>type : string +> : ^^^^^^ + + name: string; +>name : string +> : ^^^^^^ + + parent: Node | null; +>parent : Node | null +> : ^^^^^^^^^^^^^^^^ + + child: Node | null; +>child : Node | null +> : ^^^^^^^^^^^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ +} + +interface NodeConfig { + extendMarkSchema?: +>extendMarkSchema : ((this: { name: string; options: Options; }, extension: Node) => Record) | null | undefined +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + | (( + this: { +>this : { name: string; options: Options; } +> : ^^^^^^^^ ^^^^^^^^^^^ ^^^ + + name: string; +>name : string +> : ^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + }, + extension: Node, +>extension : Node +> : ^^^^^^^^^ + + ) => Record) + | null; +} + +declare class Mark { +>Mark : Mark +> : ^^^^^^^^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + config: MarkConfig; +>config : MarkConfig +> : ^^^^^^^^^^^^^^^ +} + +interface MarkConfig { + extendMarkSchema?: +>extendMarkSchema : ((this: { name: string; options: Options; }, extension: Mark) => Record) | null | undefined +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^^^^^^^^^^^^^^^ + + | (( + this: { +>this : { name: string; options: Options; } +> : ^^^^^^^^ ^^^^^^^^^^^ ^^^ + + name: string; +>name : string +> : ^^^^^^ + + options: Options; +>options : Options +> : ^^^^^^^ + + }, + extension: Mark, +>extension : Mark +> : ^^^^^^^^^ + + ) => Record) + | null; +} + +type AnyConfig = NodeConfig | MarkConfig; +>AnyConfig : AnyConfig +> : ^^^^^^^^^ + +type AnyExtension = Node | Mark; +>AnyExtension : AnyExtension +> : ^^^^^^^^^^^^ + +declare const e: AnyExtension; +>e : AnyExtension +> : ^^^^^^^^^^^^ + +type RemoveThis = T extends (...args: any) => any +>RemoveThis : RemoveThis +> : ^^^^^^^^^^^^^ +>args : any +> : ^^^ + + ? (...args: Parameters) => ReturnType +>args : Parameters +> : ^^^^^^^^^^^^^ + + : T; + +declare function getExtensionField( +>getExtensionField : (extension: AnyExtension, field: string) => RemoveThis +> : ^ ^^^^^^^^ ^^ ^^ ^^ ^^^^^ + + extension: AnyExtension, +>extension : AnyExtension +> : ^^^^^^^^^^^^ + + field: string, +>field : string +> : ^^^^^^ + +): RemoveThis; + +const extendMarkSchema = getExtensionField( +>extendMarkSchema : ((extension: Node) => Record) | ((extension: Mark) => Record) | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>getExtensionField( e, "extendMarkSchema",) : ((extension: Node) => Record) | ((extension: Mark) => Record) | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>getExtensionField : (extension: AnyExtension, field: string) => RemoveThis +> : ^ ^^^^^^^^ ^^ ^^ ^^ ^^^^^ + + e, +>e : AnyExtension +> : ^^^^^^^^^^^^ + + "extendMarkSchema", +>"extendMarkSchema" : "extendMarkSchema" +> : ^^^^^^^^^^^^^^^^^^ + +); + +declare const extension: Mark; +>extension : Mark +> : ^^^^^^^^^ + +if (extendMarkSchema) { +>extendMarkSchema : ((extension: Node) => Record) | ((extension: Mark) => Record) | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + extendMarkSchema(extension); // error +>extendMarkSchema(extension) : Record +> : ^^^^^^^^^^^^^^^^^^^ +>extendMarkSchema : ((extension: Node) => Record) | ((extension: Mark) => Record) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>extension : Mark +> : ^^^^^^^^^ +} + +export {}; + diff --git a/tests/baselines/reference/signatureCombiningRestParameters5.errors.txt b/tests/baselines/reference/signatureCombiningRestParameters5.errors.txt new file mode 100644 index 00000000000..4219a2cd575 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters5.errors.txt @@ -0,0 +1,34 @@ +signatureCombiningRestParameters5.ts(6,11): error TS2345: Argument of type 'boolean[]' is not assignable to parameter of type 'boolean'. +signatureCombiningRestParameters5.ts(22,14): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'number'. + + +==== signatureCombiningRestParameters5.ts (2 errors) ==== + declare const test1: + | ((...args: [a: string | number, b: number | boolean]) => void) + | ((...args: [c: number | boolean, d: string | boolean]) => void); + + test1(42, true); + test1(42, [true]); // error + ~~~~~~ +!!! error TS2345: Argument of type 'boolean[]' is not assignable to parameter of type 'boolean'. + + declare function test2< + A extends readonly unknown[], + B extends readonly unknown[], + >( + c: (...args: A) => void, + d: (...args: B) => void, + e: (arg: typeof c | typeof d) => void, + ): void; + + test2( + (a: number | boolean, b: string | number) => {}, + (c: string | boolean, d: number | boolean) => {}, + (cb) => { + cb(true, 42); + cb(true, [42]); // error + ~~~~ +!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'number'. + }, + ); + \ No newline at end of file diff --git a/tests/baselines/reference/signatureCombiningRestParameters5.symbols b/tests/baselines/reference/signatureCombiningRestParameters5.symbols new file mode 100644 index 00000000000..a4128967b32 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters5.symbols @@ -0,0 +1,69 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters5.ts] //// + +=== signatureCombiningRestParameters5.ts === +declare const test1: +>test1 : Symbol(test1, Decl(signatureCombiningRestParameters5.ts, 0, 13)) + + | ((...args: [a: string | number, b: number | boolean]) => void) +>args : Symbol(args, Decl(signatureCombiningRestParameters5.ts, 1, 6)) + + | ((...args: [c: number | boolean, d: string | boolean]) => void); +>args : Symbol(args, Decl(signatureCombiningRestParameters5.ts, 2, 6)) + +test1(42, true); +>test1 : Symbol(test1, Decl(signatureCombiningRestParameters5.ts, 0, 13)) + +test1(42, [true]); // error +>test1 : Symbol(test1, Decl(signatureCombiningRestParameters5.ts, 0, 13)) + +declare function test2< +>test2 : Symbol(test2, Decl(signatureCombiningRestParameters5.ts, 5, 18)) + + A extends readonly unknown[], +>A : Symbol(A, Decl(signatureCombiningRestParameters5.ts, 7, 23)) + + B extends readonly unknown[], +>B : Symbol(B, Decl(signatureCombiningRestParameters5.ts, 8, 31)) + +>( + c: (...args: A) => void, +>c : Symbol(c, Decl(signatureCombiningRestParameters5.ts, 10, 2)) +>args : Symbol(args, Decl(signatureCombiningRestParameters5.ts, 11, 6)) +>A : Symbol(A, Decl(signatureCombiningRestParameters5.ts, 7, 23)) + + d: (...args: B) => void, +>d : Symbol(d, Decl(signatureCombiningRestParameters5.ts, 11, 26)) +>args : Symbol(args, Decl(signatureCombiningRestParameters5.ts, 12, 6)) +>B : Symbol(B, Decl(signatureCombiningRestParameters5.ts, 8, 31)) + + e: (arg: typeof c | typeof d) => void, +>e : Symbol(e, Decl(signatureCombiningRestParameters5.ts, 12, 26)) +>arg : Symbol(arg, Decl(signatureCombiningRestParameters5.ts, 13, 6)) +>c : Symbol(c, Decl(signatureCombiningRestParameters5.ts, 10, 2)) +>d : Symbol(d, Decl(signatureCombiningRestParameters5.ts, 11, 26)) + +): void; + +test2( +>test2 : Symbol(test2, Decl(signatureCombiningRestParameters5.ts, 5, 18)) + + (a: number | boolean, b: string | number) => {}, +>a : Symbol(a, Decl(signatureCombiningRestParameters5.ts, 17, 3)) +>b : Symbol(b, Decl(signatureCombiningRestParameters5.ts, 17, 23)) + + (c: string | boolean, d: number | boolean) => {}, +>c : Symbol(c, Decl(signatureCombiningRestParameters5.ts, 18, 3)) +>d : Symbol(d, Decl(signatureCombiningRestParameters5.ts, 18, 23)) + + (cb) => { +>cb : Symbol(cb, Decl(signatureCombiningRestParameters5.ts, 19, 3)) + + cb(true, 42); +>cb : Symbol(cb, Decl(signatureCombiningRestParameters5.ts, 19, 3)) + + cb(true, [42]); // error +>cb : Symbol(cb, Decl(signatureCombiningRestParameters5.ts, 19, 3)) + + }, +); + diff --git a/tests/baselines/reference/signatureCombiningRestParameters5.types b/tests/baselines/reference/signatureCombiningRestParameters5.types new file mode 100644 index 00000000000..2d9131ecff8 --- /dev/null +++ b/tests/baselines/reference/signatureCombiningRestParameters5.types @@ -0,0 +1,121 @@ +//// [tests/cases/compiler/signatureCombiningRestParameters5.ts] //// + +=== signatureCombiningRestParameters5.ts === +declare const test1: +>test1 : ((a: string | number, b: number | boolean) => void) | ((c: number | boolean, d: string | boolean) => void) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ + + | ((...args: [a: string | number, b: number | boolean]) => void) +>args : [a: string | number, b: number | boolean] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + | ((...args: [c: number | boolean, d: string | boolean]) => void); +>args : [c: number | boolean, d: string | boolean] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +test1(42, true); +>test1(42, true) : void +> : ^^^^ +>test1 : ((a: string | number, b: number | boolean) => void) | ((c: number | boolean, d: string | boolean) => void) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ +>42 : 42 +> : ^^ +>true : true +> : ^^^^ + +test1(42, [true]); // error +>test1(42, [true]) : void +> : ^^^^ +>test1 : ((a: string | number, b: number | boolean) => void) | ((c: number | boolean, d: string | boolean) => void) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ +>42 : 42 +> : ^^ +>[true] : boolean[] +> : ^^^^^^^^^ +>true : true +> : ^^^^ + +declare function test2< +>test2 : (c: (...args: A) => void, d: (...args: B) => void, e: (arg: typeof c | typeof d) => void) => void +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ + + A extends readonly unknown[], + B extends readonly unknown[], +>( + c: (...args: A) => void, +>c : (...args: A) => void +> : ^^^^ ^^ ^^^^^ +>args : A +> : ^ + + d: (...args: B) => void, +>d : (...args: B) => void +> : ^^^^ ^^ ^^^^^ +>args : B +> : ^ + + e: (arg: typeof c | typeof d) => void, +>e : (arg: typeof c | typeof d) => void +> : ^ ^^ ^^^^^ +>arg : ((...args: A) => void) | ((...args: B) => void) +> : ^^^^^ ^^ ^^^^^ ^^^^^^^^^ ^^ ^^^^^ ^ +>c : (...args: A) => void +> : ^^^^ ^^ ^^^^^ +>d : (...args: B) => void +> : ^^^^ ^^ ^^^^^ + +): void; + +test2( +>test2( (a: number | boolean, b: string | number) => {}, (c: string | boolean, d: number | boolean) => {}, (cb) => { cb(true, 42); cb(true, [42]); // error },) : void +> : ^^^^ +>test2 : (c: (...args: A) => void, d: (...args: B) => void, e: (arg: typeof c | typeof d) => void) => void +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ + + (a: number | boolean, b: string | number) => {}, +>(a: number | boolean, b: string | number) => {} : (a: number | boolean, b: string | number) => void +> : ^ ^^ ^^ ^^ ^^^^^^^^^ +>a : number | boolean +> : ^^^^^^^^^^^^^^^^ +>b : string | number +> : ^^^^^^^^^^^^^^^ + + (c: string | boolean, d: number | boolean) => {}, +>(c: string | boolean, d: number | boolean) => {} : (c: string | boolean, d: number | boolean) => void +> : ^ ^^ ^^ ^^ ^^^^^^^^^ +>c : string | boolean +> : ^^^^^^^^^^^^^^^^ +>d : number | boolean +> : ^^^^^^^^^^^^^^^^ + + (cb) => { +>(cb) => { cb(true, 42); cb(true, [42]); // error } : (cb: ((a: number | boolean, b: string | number) => void) | ((c: string | boolean, d: number | boolean) => void)) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ +>cb : ((a: number | boolean, b: string | number) => void) | ((c: string | boolean, d: number | boolean) => void) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ + + cb(true, 42); +>cb(true, 42) : void +> : ^^^^ +>cb : ((a: number | boolean, b: string | number) => void) | ((c: string | boolean, d: number | boolean) => void) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ +>true : true +> : ^^^^ +>42 : 42 +> : ^^ + + cb(true, [42]); // error +>cb(true, [42]) : void +> : ^^^^ +>cb : ((a: number | boolean, b: string | number) => void) | ((c: string | boolean, d: number | boolean) => void) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ +>true : true +> : ^^^^ +>[42] : number[] +> : ^^^^^^^^ +>42 : 42 +> : ^^ + + }, +); + diff --git a/tests/cases/compiler/signatureCombiningRestParameters1.ts b/tests/cases/compiler/signatureCombiningRestParameters1.ts new file mode 100644 index 00000000000..d2603b9998c --- /dev/null +++ b/tests/cases/compiler/signatureCombiningRestParameters1.ts @@ -0,0 +1,26 @@ +// @strict: true +// @lib: esnext +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/58371 + +type T1 = "A" | "B"; + +type T2 = { + C: [string]; + D: [number]; +}; + +declare const map: { + [K in T1 | keyof T2]: (...args: K extends keyof T2 ? T2[K] : []) => unknown; +}; + +declare const args: any; + +for (const [key, fn] of Object.entries(map)) { + fn(...args); +} + +const test2: ((a: number, ...args: []) => void) & + ((b: string) => void) & + ((c: boolean) => void) = (arg) => {}; diff --git a/tests/cases/compiler/signatureCombiningRestParameters2.ts b/tests/cases/compiler/signatureCombiningRestParameters2.ts new file mode 100644 index 00000000000..c77479eba45 --- /dev/null +++ b/tests/cases/compiler/signatureCombiningRestParameters2.ts @@ -0,0 +1,13 @@ +// @strict: true +// @lib: dom,esnext +// @noEmit: true + +interface Console { + log(message?: any, ...optionalParams: any[]): void; +} + +let logs: string[] = []; +let originalLog: typeof console.log; +console.log = (...args) => { + logs.push(...args); +}; diff --git a/tests/cases/compiler/signatureCombiningRestParameters3.ts b/tests/cases/compiler/signatureCombiningRestParameters3.ts new file mode 100644 index 00000000000..0d07c1b2e6a --- /dev/null +++ b/tests/cases/compiler/signatureCombiningRestParameters3.ts @@ -0,0 +1,87 @@ +// @strict: true +// @noEmit: true + +interface ExtensionConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Mark, + ) => Record) + | null; +} + +declare class Extension { + type: string; + name: string; + parent: Extension | null; + child: Extension | null; + options: Options; + config: ExtensionConfig; +} + +declare class Node { + type: string; + name: string; + parent: Node | null; + child: Node | null; + options: Options; +} + +interface NodeConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Node, + ) => Record) + | null; +} + +declare class Mark { + options: Options; + config: MarkConfig; +} + +interface MarkConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Mark, + ) => Record) + | null; +} + +type AnyConfig = ExtensionConfig | NodeConfig | MarkConfig; +type AnyExtension = Extension | Node | Mark; + +declare const e: AnyExtension; + +type RemoveThis = T extends (...args: any) => any + ? (...args: Parameters) => ReturnType + : T; + +declare function getExtensionField( + extension: AnyExtension, + field: string, +): RemoveThis; + +const extendMarkSchema = getExtensionField( + e, + "extendMarkSchema", +); + +declare const extension: Mark; + +if (extendMarkSchema) { + extendMarkSchema(extension); // error +} + +export {}; diff --git a/tests/cases/compiler/signatureCombiningRestParameters4.ts b/tests/cases/compiler/signatureCombiningRestParameters4.ts new file mode 100644 index 00000000000..8ae7088c218 --- /dev/null +++ b/tests/cases/compiler/signatureCombiningRestParameters4.ts @@ -0,0 +1,66 @@ +// @strict: true +// @noEmit: true + +declare class Node { + type: string; + name: string; + parent: Node | null; + child: Node | null; + options: Options; +} + +interface NodeConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Node, + ) => Record) + | null; +} + +declare class Mark { + options: Options; + config: MarkConfig; +} + +interface MarkConfig { + extendMarkSchema?: + | (( + this: { + name: string; + options: Options; + }, + extension: Mark, + ) => Record) + | null; +} + +type AnyConfig = NodeConfig | MarkConfig; +type AnyExtension = Node | Mark; + +declare const e: AnyExtension; + +type RemoveThis = T extends (...args: any) => any + ? (...args: Parameters) => ReturnType + : T; + +declare function getExtensionField( + extension: AnyExtension, + field: string, +): RemoveThis; + +const extendMarkSchema = getExtensionField( + e, + "extendMarkSchema", +); + +declare const extension: Mark; + +if (extendMarkSchema) { + extendMarkSchema(extension); // error +} + +export {}; diff --git a/tests/cases/compiler/signatureCombiningRestParameters5.ts b/tests/cases/compiler/signatureCombiningRestParameters5.ts new file mode 100644 index 00000000000..cdcaeb71935 --- /dev/null +++ b/tests/cases/compiler/signatureCombiningRestParameters5.ts @@ -0,0 +1,27 @@ +// @strict: true +// @noEmit: true + +declare const test1: + | ((...args: [a: string | number, b: number | boolean]) => void) + | ((...args: [c: number | boolean, d: string | boolean]) => void); + +test1(42, true); +test1(42, [true]); // error + +declare function test2< + A extends readonly unknown[], + B extends readonly unknown[], +>( + c: (...args: A) => void, + d: (...args: B) => void, + e: (arg: typeof c | typeof d) => void, +): void; + +test2( + (a: number | boolean, b: string | number) => {}, + (c: string | boolean, d: number | boolean) => {}, + (cb) => { + cb(true, 42); + cb(true, [42]); // error + }, +); diff --git a/tests/cases/fourslash/quickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1.ts b/tests/cases/fourslash/quickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1.ts new file mode 100644 index 00000000000..1c77ece9fa4 --- /dev/null +++ b/tests/cases/fourslash/quickInfoContextuallyTypedSignatureOptionalParameterFromIntersection1.ts @@ -0,0 +1,12 @@ +/// + +// @strict: true + +//// const optionals: ((a?: number) => unknown) & ((b?: string) => unknown) = ( +//// arg, +//// ) =/**/> {}; + +verify.quickInfoAt( + "", + `function(arg: string | number | undefined): void`, +); \ No newline at end of file