Skip to content
Open
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
13 changes: 7 additions & 6 deletions tsc/internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16918,11 +16918,12 @@ func (c *Checker) checkDeclarationInitializer(declaration *ast.Node, checkMode C
func (c *Checker) padObjectLiteralType(t *Type, pattern *ast.Node) *Type {
var missingElements []*ast.Node
for _, e := range pattern.Elements() {
if e.Initializer() != nil {
name := c.getPropertyNameFromBindingElement(e)
if name != ast.InternalSymbolNameMissing && c.getPropertyOfType(t, name) == nil {
missingElements = append(missingElements, e)
}
if hasDotDotDotToken(e) {
continue
}
Comment on lines +16924 to +16926
name := c.getPropertyNameFromBindingElement(e)
if name != ast.InternalSymbolNameMissing && c.getPropertyOfType(t, name) == nil {
missingElements = append(missingElements, e)
}
}
if len(missingElements) == 0 {
Expand All @@ -16934,7 +16935,7 @@ func (c *Checker) padObjectLiteralType(t *Type, pattern *ast.Node) *Type {
}
for _, e := range missingElements {
symbol := c.newSymbol(ast.SymbolFlagsProperty|ast.SymbolFlagsOptional, c.getPropertyNameFromBindingElement(e))
c.valueSymbolLinks.Get(symbol).resolvedType = c.getTypeFromBindingElement(e, false /*includePatternInType*/, false /*reportErrors*/)
c.valueSymbolLinks.Get(symbol).resolvedType = c.getTypeFromBindingElement(e, false /*includePatternInType*/, true /*reportErrors*/)
members[symbol.Name] = symbol
}
result := c.newAnonymousType(t.symbol, members, nil, nil, c.getIndexInfosOfType(t))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
inferredRestTypeFixedOnce.ts(2,9): error TS7031: Binding element 'cancelable' implicitly has an 'any' type.


==== inferredRestTypeFixedOnce.ts (1 errors) ====
function wrap<Args extends unknown[]>(_: (...args: Args) => void) {}
wrap(({ cancelable } = {}) => {});
~~~~~~~~~~
!!! error TS7031: Binding element 'cancelable' implicitly has an 'any' type.

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/checked.js(3,5): error TS7031: Binding element 'required' implicitly has an 'any' type.
/checked.js(8,5): error TS7031: Binding element 'required' implicitly has an 'any' type.
/main.ts(5,5): error TS7031: Binding element 'required' implicitly has an 'any' type.
/main.ts(10,5): error TS7031: Binding element 'required' implicitly has an 'any' type.
/main.ts(15,5): error TS7031: Binding element 'required' implicitly has an 'any' type.


==== /unchecked.js (0 errors) ====
export const uncheckedObject = ({
required,
optional = false,
} = {}) => {};

export const uncheckedArray = ([
required,
optional = false,
] = []) => {};

==== /checked.js (2 errors) ====
// @ts-check
export const checkedObject = ({
required,
~~~~~~~~
!!! error TS7031: Binding element 'required' implicitly has an 'any' type.
optional = false,
} = {}) => {};

export const checkedArray = ([
required,
~~~~~~~~
!!! error TS7031: Binding element 'required' implicitly has an 'any' type.
optional = false,
] = []) => {};

==== /main.ts (3 errors) ====
import { checkedArray, checkedObject } from "./checked";
import { uncheckedArray, uncheckedObject } from "./unchecked";

export const typedObject = ({
required,
~~~~~~~~
!!! error TS7031: Binding element 'required' implicitly has an 'any' type.
optional = false,
} = {}) => {};

export const typedArray = ([
required,
~~~~~~~~
!!! error TS7031: Binding element 'required' implicitly has an 'any' type.
optional = false,
] = []) => {};

export const typedObjectRest = ({
required,
~~~~~~~~
!!! error TS7031: Binding element 'required' implicitly has an 'any' type.
...rest
} = {}) => {
rest;
};

uncheckedObject({ required: "value" });
uncheckedArray(["value"]);
checkedObject({ required: "value" });
checkedArray(["value"]);
typedObject({ required: "value" });
typedArray(["value"]);

Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
//// [tests/cases/compiler/objectBindingPatternDefaultMissingElements.ts] ////

=== /unchecked.js ===
export const uncheckedObject = ({
>uncheckedObject : Symbol(uncheckedObject, Decl(unchecked.js, 0, 12))

required,
>required : Symbol(required, Decl(unchecked.js, 0, 33))

optional = false,
>optional : Symbol(optional, Decl(unchecked.js, 1, 13))

} = {}) => {};

export const uncheckedArray = ([
>uncheckedArray : Symbol(uncheckedArray, Decl(unchecked.js, 5, 12))

required,
>required : Symbol(required, Decl(unchecked.js, 5, 32))

optional = false,
>optional : Symbol(optional, Decl(unchecked.js, 6, 13))

] = []) => {};

=== /checked.js ===
// @ts-check
export const checkedObject = ({
>checkedObject : Symbol(checkedObject, Decl(checked.js, 1, 12))

required,
>required : Symbol(required, Decl(checked.js, 1, 31))

optional = false,
>optional : Symbol(optional, Decl(checked.js, 2, 13))

} = {}) => {};

export const checkedArray = ([
>checkedArray : Symbol(checkedArray, Decl(checked.js, 6, 12))

required,
>required : Symbol(required, Decl(checked.js, 6, 30))

optional = false,
>optional : Symbol(optional, Decl(checked.js, 7, 13))

] = []) => {};

=== /main.ts ===
import { checkedArray, checkedObject } from "./checked";
>checkedArray : Symbol(checkedArray, Decl(main.ts, 0, 8))
>checkedObject : Symbol(checkedObject, Decl(main.ts, 0, 22))

import { uncheckedArray, uncheckedObject } from "./unchecked";
>uncheckedArray : Symbol(uncheckedArray, Decl(main.ts, 1, 8))
>uncheckedObject : Symbol(uncheckedObject, Decl(main.ts, 1, 24))

export const typedObject = ({
>typedObject : Symbol(typedObject, Decl(main.ts, 3, 12))

required,
>required : Symbol(required, Decl(main.ts, 3, 29))

optional = false,
>optional : Symbol(optional, Decl(main.ts, 4, 13))

} = {}) => {};

export const typedArray = ([
>typedArray : Symbol(typedArray, Decl(main.ts, 8, 12))

required,
>required : Symbol(required, Decl(main.ts, 8, 28))

optional = false,
>optional : Symbol(optional, Decl(main.ts, 9, 13))

] = []) => {};

export const typedObjectRest = ({
>typedObjectRest : Symbol(typedObjectRest, Decl(main.ts, 13, 12))

required,
>required : Symbol(required, Decl(main.ts, 13, 33))

...rest
>rest : Symbol(rest, Decl(main.ts, 14, 13))

} = {}) => {
rest;
>rest : Symbol(rest, Decl(main.ts, 14, 13))

};

uncheckedObject({ required: "value" });
>uncheckedObject : Symbol(uncheckedObject, Decl(main.ts, 1, 24))
>required : Symbol(required, Decl(main.ts, 20, 17))

uncheckedArray(["value"]);
>uncheckedArray : Symbol(uncheckedArray, Decl(main.ts, 1, 8))

checkedObject({ required: "value" });
>checkedObject : Symbol(checkedObject, Decl(main.ts, 0, 22))
>required : Symbol(required, Decl(main.ts, 22, 15))

checkedArray(["value"]);
>checkedArray : Symbol(checkedArray, Decl(main.ts, 0, 8))

typedObject({ required: "value" });
>typedObject : Symbol(typedObject, Decl(main.ts, 3, 12))
>required : Symbol(required, Decl(main.ts, 24, 13))

typedArray(["value"]);
>typedArray : Symbol(typedArray, Decl(main.ts, 8, 12))

Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//// [tests/cases/compiler/objectBindingPatternDefaultMissingElements.ts] ////

=== /unchecked.js ===
export const uncheckedObject = ({
>uncheckedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void
>({ required, optional = false,} = {}) => {} : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void

required,
>required : any

optional = false,
>optional : boolean
>false : false

} = {}) => {};
>{} : {}

export const uncheckedArray = ([
>uncheckedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>([ required, optional = false,] = []) => {} : ([required, optional,]?: [any?, (boolean | undefined)?]) => void

required,
>required : any

optional = false,
>optional : boolean
>false : false

] = []) => {};
>[] : []

=== /checked.js ===
// @ts-check
export const checkedObject = ({
>checkedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void
>({ required, optional = false,} = {}) => {} : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void

required,
>required : any

optional = false,
>optional : boolean
>false : false

} = {}) => {};
>{} : {}

export const checkedArray = ([
>checkedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>([ required, optional = false,] = []) => {} : ([required, optional,]?: [any?, (boolean | undefined)?]) => void

required,
>required : any

optional = false,
>optional : boolean
>false : false

] = []) => {};
>[] : []

=== /main.ts ===
import { checkedArray, checkedObject } from "./checked";
>checkedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>checkedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void

import { uncheckedArray, uncheckedObject } from "./unchecked";
>uncheckedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>uncheckedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void

export const typedObject = ({
>typedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void
>({ required, optional = false,} = {}) => {} : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void

required,
>required : any

optional = false,
>optional : boolean
>false : false

} = {}) => {};
>{} : {}

export const typedArray = ([
>typedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>([ required, optional = false,] = []) => {} : ([required, optional,]?: [any?, (boolean | undefined)?]) => void

required,
>required : any

optional = false,
>optional : boolean
>false : false

] = []) => {};
>[] : []

export const typedObjectRest = ({
>typedObjectRest : ({ required, ...rest }?: { required?: any; }) => void
>({ required, ...rest} = {}) => { rest;} : ({ required, ...rest }?: { required?: any; }) => void

required,
>required : any

...rest
>rest : {}

} = {}) => {
>{} : {}

rest;
>rest : {}

};

uncheckedObject({ required: "value" });
>uncheckedObject({ required: "value" }) : void
>uncheckedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void
>{ required: "value" } : { required: string; }
>required : string
>"value" : "value"

uncheckedArray(["value"]);
>uncheckedArray(["value"]) : void
>uncheckedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>["value"] : [string]
>"value" : "value"

checkedObject({ required: "value" });
>checkedObject({ required: "value" }) : void
>checkedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void
>{ required: "value" } : { required: string; }
>required : string
>"value" : "value"

checkedArray(["value"]);
>checkedArray(["value"]) : void
>checkedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>["value"] : [string]
>"value" : "value"

typedObject({ required: "value" });
>typedObject({ required: "value" }) : void
>typedObject : ({ required, optional, }?: { optional?: boolean | undefined; required?: any; }) => void
>{ required: "value" } : { required: string; }
>required : string
>"value" : "value"

typedArray(["value"]);
>typedArray(["value"]) : void
>typedArray : ([required, optional,]?: [any?, (boolean | undefined)?]) => void
>["value"] : [string]
>"value" : "value"

Loading