Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1693,8 +1693,7 @@ type SignatureToSignatureDeclarationOptions struct {
func (b *nodeBuilderImpl) signatureToSignatureDeclarationHelper(signature *Signature, kind ast.Kind, options *SignatureToSignatureDeclarationOptions) *ast.Node {
var typeParameters []*ast.Node

expandedParams := b.ch.getExpandedParameters(signature, true /*skipUnionExpanding*/)[0]
cleanup := b.enterNewScope(signature.declaration, expandedParams, signature.typeParameters, signature.parameters, signature.mapper)
cleanup := b.enterNewScope(signature.declaration, signature.parameters, signature.typeParameters, signature.parameters, signature.mapper)
b.ctx.approximateLength += 3
// Usually a signature contributes a few more characters than this, but 3 is the minimum

Expand All @@ -1710,10 +1709,7 @@ func (b *nodeBuilderImpl) signatureToSignatureDeclarationHelper(signature *Signa

restoreFlags := b.saveRestoreFlags()
b.ctx.flags &^= nodebuilder.FlagsSuppressAnyReturnType
// If the expanded parameter list had a variadic in a non-trailing position, don't expand it
parameters := core.Map(core.IfElse(core.Some(expandedParams, func(p *ast.Symbol) bool {
return p != expandedParams[len(expandedParams)-1] && p.CheckFlags&ast.CheckFlagsRestParameter != 0
}), signature.parameters, expandedParams), func(parameter *ast.Symbol) *ast.Node {
parameters := core.Map(signature.parameters, func(parameter *ast.Symbol) *ast.Node {
return b.symbolToParameterDeclaration(parameter, kind == ast.KindConstructor)
})
var thisParameter *ast.Node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ declare const itNum: Iterable<number>

;(function(a, ...rest) {})('', true, ...itNum)
>(function(a, ...rest) {})('', true, ...itNum) : void
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest: Iterable<number>[]) => void
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest: Iterable<number>[]) => void
>(function(a, ...rest) {}) : (a: string, ...rest: [boolean, ...Iterable<number>[]]) => void
>function(a, ...rest) {} : (a: string, ...rest: [boolean, ...Iterable<number>[]]) => void
>a : string
>rest : [boolean, ...Iterable<number>[]]
>'' : ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- old.argumentsSpreadRestIterables(target=es5).types
+++ new.argumentsSpreadRestIterables(target=es5).types
@@= skipped -23, +23 lines =@@

;(function(a, ...rest) {})('', true, ...itNum)
>(function(a, ...rest) {})('', true, ...itNum) : void
->(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest: Iterable<number>[]) => void
->function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest: Iterable<number>[]) => void
+>(function(a, ...rest) {}) : (a: string, ...rest: [boolean, ...Iterable<number>[]]) => void
+>function(a, ...rest) {} : (a: string, ...rest: [boolean, ...Iterable<number>[]]) => void
>a : string
>rest : [boolean, ...Iterable<number>[]]
>'' : ""
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ declare const itNum: Iterable<number>

;(function(a, ...rest) {})('', true, ...itNum)
>(function(a, ...rest) {})('', true, ...itNum) : void
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest: number[]) => void
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest: number[]) => void
>(function(a, ...rest) {}) : (a: string, ...rest: [boolean, ...number[]]) => void
>function(a, ...rest) {} : (a: string, ...rest: [boolean, ...number[]]) => void
>a : string
>rest : [boolean, ...number[]]
>'' : ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- old.argumentsSpreadRestIterables(target=esnext).types
+++ new.argumentsSpreadRestIterables(target=esnext).types
@@= skipped -23, +23 lines =@@

;(function(a, ...rest) {})('', true, ...itNum)
>(function(a, ...rest) {})('', true, ...itNum) : void
->(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest: number[]) => void
->function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest: number[]) => void
+>(function(a, ...rest) {}) : (a: string, ...rest: [boolean, ...number[]]) => void
+>function(a, ...rest) {} : (a: string, ...rest: [boolean, ...number[]]) => void
>a : string
>rest : [boolean, ...number[]]
>'' : ""
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,19 @@ declare function useReduxDispatch1<T extends IDestructuring<TFuncs1>>(destructur
>destructuring : Destructuring<{ funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }, T>

const {} = useReduxDispatch1(
>useReduxDispatch1( (d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), })) : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
>useReduxDispatch1( (d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), })) : { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }
>useReduxDispatch1 : <T extends IDestructuring<{ funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }>>(destructuring: Destructuring<{ funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }, T>) => T

(d, f) => ({
>(d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : (d: Dispatch<any>, f: { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }) => { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
>(d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : (d: Dispatch<any>, f: { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }) => { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }
>d : Dispatch<any>
>f : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
>({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
>{ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), } : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
>({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }
>{ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), } : { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }

funcA: (...p) => d(f.funcA(...p)), // p should be inferrable
>funcA : (a: boolean) => void
>(...p) => d(f.funcA(...p)) : (a: boolean) => void
>funcA : (...p: [a: boolean]) => void
>(...p) => d(f.funcA(...p)) : (...p: [a: boolean]) => void
>p : [a: boolean]
>d(f.funcA(...p)) : void
>d : Dispatch<any>
Expand All @@ -100,8 +100,8 @@ const {} = useReduxDispatch1(
>p : [a: boolean]

funcB: (...p) => d(f.funcB(...p)),
>funcB : (b: string, bb: string) => void
>(...p) => d(f.funcB(...p)) : (b: string, bb: string) => void
>funcB : (...p: [b: string, bb: string]) => void
>(...p) => d(f.funcB(...p)) : (...p: [b: string, bb: string]) => void
>p : [b: string, bb: string]
>d(f.funcB(...p)) : void
>d : Dispatch<any>
Expand All @@ -113,8 +113,8 @@ const {} = useReduxDispatch1(
>p : [b: string, bb: string]

funcC: (...p) => d(f.funcC(...p)),
>funcC : (c: number, cc: number, ccc: boolean) => void
>(...p) => d(f.funcC(...p)) : (c: number, cc: number, ccc: boolean) => void
>funcC : (...p: [c: number, cc: number, ccc: boolean]) => void
>(...p) => d(f.funcC(...p)) : (...p: [c: number, cc: number, ccc: boolean]) => void
>p : [c: number, cc: number, ccc: boolean]
>d(f.funcC(...p)) : void
>d : Dispatch<any>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,48 @@
>destructuring : Destructuring<{ funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }, T>

const {} = useReduxDispatch1(
>useReduxDispatch1( (d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), })) : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
->useReduxDispatch1( (d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), })) : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
->useReduxDispatch1 : <T extends IDestructuring<TFuncs1>>(destructuring: Destructuring<TFuncs1, T>) => T
+>useReduxDispatch1( (d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), })) : { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }
+>useReduxDispatch1 : <T extends IDestructuring<{ funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }>>(destructuring: Destructuring<{ funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }, T>) => T

(d, f) => ({
>(d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : (d: Dispatch<any>, f: { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }) => { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
->(d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : (d: Dispatch<any>, f: { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }) => { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
+>(d, f) => ({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : (d: Dispatch<any>, f: { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }) => { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }
>d : Dispatch<any>
>f : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
->({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
->{ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), } : { funcA: (a: boolean) => void; funcB: (b: string, bb: string) => void; funcC: (c: number, cc: number, ccc: boolean) => void; }
+>({ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), }) : { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }
+>{ funcA: (...p) => d(f.funcA(...p)), // p should be inferrable funcB: (...p) => d(f.funcB(...p)), funcC: (...p) => d(f.funcC(...p)), } : { funcA: (...p: [a: boolean]) => void; funcB: (...p: [b: string, bb: string]) => void; funcC: (...p: [c: number, cc: number, ccc: boolean]) => void; }

funcA: (...p) => d(f.funcA(...p)), // p should be inferrable
->funcA : (a: boolean) => void
->(...p) => d(f.funcA(...p)) : (a: boolean) => void
+>funcA : (...p: [a: boolean]) => void
+>(...p) => d(f.funcA(...p)) : (...p: [a: boolean]) => void
>p : [a: boolean]
>d(f.funcA(...p)) : void
>d : Dispatch<any>
@@= skipped -28, +28 lines =@@
>p : [a: boolean]

funcB: (...p) => d(f.funcB(...p)),
->funcB : (b: string, bb: string) => void
->(...p) => d(f.funcB(...p)) : (b: string, bb: string) => void
+>funcB : (...p: [b: string, bb: string]) => void
+>(...p) => d(f.funcB(...p)) : (...p: [b: string, bb: string]) => void
>p : [b: string, bb: string]
>d(f.funcB(...p)) : void
>d : Dispatch<any>
@@= skipped -13, +13 lines =@@
>p : [b: string, bb: string]

funcC: (...p) => d(f.funcC(...p)),
->funcC : (c: number, cc: number, ccc: boolean) => void
->(...p) => d(f.funcC(...p)) : (c: number, cc: number, ccc: boolean) => void
+>funcC : (...p: [c: number, cc: number, ccc: boolean]) => void
+>(...p) => d(f.funcC(...p)) : (...p: [c: number, cc: number, ccc: boolean]) => void
>p : [c: number, cc: number, ccc: boolean]
>d(f.funcC(...p)) : void
>d : Dispatch<any>
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ const f7: () => any = (x?) => 0; // Implicit any error

const f8: () => any = (...x) => 0; // []
>f8 : () => any
>(...x) => 0 : () => number
>(...x) => 0 : (...x: []) => number
>x : []
>0 : 0

Expand Down Expand Up @@ -240,9 +240,9 @@ g6((x?) => 0); // Implicit any error
>0 : 0

g6((...x) => 0); // []
>g6((...x) => 0) : () => number
>g6((...x) => 0) : (...x: []) => number
>g6 : <T extends () => any>(x: T) => T
>(...x) => 0 : () => number
>(...x) => 0 : (...x: []) => number
>x : []
>0 : 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,24 @@
+>id5 : <T extends (x?: number | undefined) => any>(input: T) => T
>function (foo = 42) { return foo } : (foo?: number | undefined) => number
>foo : number | undefined
>42 : 42
>42 : 42
@@= skipped -57, +57 lines =@@

const f8: () => any = (...x) => 0; // []
>f8 : () => any
->(...x) => 0 : () => number
+>(...x) => 0 : (...x: []) => number
>x : []
>0 : 0

@@= skipped -85, +85 lines =@@
>0 : 0

g6((...x) => 0); // []
->g6((...x) => 0) : () => number
+>g6((...x) => 0) : (...x: []) => number
>g6 : <T extends () => any>(x: T) => T
->(...x) => 0 : () => number
+>(...x) => 0 : (...x: []) => number
>x : []
>0 : 0
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ function ff1() {
>Keys : keyof { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }

const funs: { [P in Keys]: (...args: ArgMap[P]) => void } = {
>funs : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }
>funs : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[P]
>{ sum: (a, b) => a + b, concat: (a, b, c) => a + b + c } : { sum: (a: number, b: number) => number; concat: (a: string, b: string, c: string) => string; }

Expand Down Expand Up @@ -522,14 +522,14 @@ function ff1() {
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]

const fn = funs[funKey];
>fn : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K]
>funs[funKey] : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K]
>funs : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }
>fn : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }[K]
>funs[funKey] : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }[K]
>funs : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }
>funKey : K

fn(...args);
>fn(...args) : void
>fn : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K]
>fn : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }[K]
>...args : string | number
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,35 @@

processEvents([
>processEvents([ { name: "click", callback: ev => console.log(ev) }, { name: "scroll", callback: ev => console.log(ev) },]) : void
@@= skipped -180, +180 lines =@@
@@= skipped -55, +55 lines =@@
>Keys : keyof { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }

const funs: { [P in Keys]: (...args: ArgMap[P]) => void } = {
->funs : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }
+>funs : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[P]
>{ sum: (a, b) => a + b, concat: (a, b, c) => a + b + c } : { sum: (a: number, b: number) => number; concat: (a: string, b: string, c: string) => string; }

@@= skipped -31, +31 lines =@@
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]

const fn = funs[funKey];
->fn : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K]
->funs[funKey] : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K]
->funs : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }
+>fn : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }[K]
+>funs[funKey] : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }[K]
+>funs : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }
>funKey : K

fn(...args);
>fn(...args) : void
->fn : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K]
+>fn : { concat: (...args: [a: string, b: string, c: string]) => void; sum: (...args: [a: number, b: number]) => void; }[K]
>...args : string | number
>args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K]
}
@@= skipped -94, +94 lines =@@
}

function f4<K extends keyof ArgMap>(x: Funcs[keyof ArgMap], y: Funcs[K]) {
Expand Down
Loading