-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Improve excess property checks #28854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(9,18): error TS2322: Type '{ forword: string; }' is not assignable to type 'Book'. | ||
Object literal may only specify known properties, but 'forword' does not exist in type 'Book'. Did you mean to write 'foreword'? | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(11,27): error TS2322: Type '{ foreward: string; }' is not assignable to type 'string | Book'. | ||
Object literal may only specify known properties, and 'foreward' does not exist in type 'string | Book'. | ||
Object literal may only specify known properties, but 'foreward' does not exist in type 'Book'. Did you mean to write 'foreword'? | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(13,53): error TS2322: Type '({ foreword: string; } | { forwards: string; })[]' is not assignable to type 'Book | Book[]'. | ||
Type '({ foreword: string; } | { forwards: string; })[]' is not assignable to type 'Book[]'. | ||
Type '{ foreword: string; } | { forwards: string; }' is not assignable to type 'Book'. | ||
|
@@ -13,17 +13,27 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(17,26): error TS2322: Type | |
Object literal may only specify known properties, but 'foreward' does not exist in type 'Book & Cover'. Did you mean to write 'foreword'? | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(19,57): error TS2322: Type '{ foreword: string; color: string; price: number; }' is not assignable to type 'Book & Cover'. | ||
Object literal may only specify known properties, and 'price' does not exist in type 'Book & Cover'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(21,43): error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'Book & number'. | ||
Object literal may only specify known properties, and 'price' does not exist in type 'Book & number'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(21,5): error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'Book & number'. | ||
Type '{ foreword: string; price: number; }' is not assignable to type 'number'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(23,29): error TS2322: Type '{ couleur: string; }' is not assignable to type 'Cover | Cover[]'. | ||
Object literal may only specify known properties, and 'couleur' does not exist in type 'Cover | Cover[]'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(25,27): error TS2322: Type '{ forewarned: string; }' is not assignable to type 'Book | Book[]'. | ||
Object literal may only specify known properties, and 'forewarned' does not exist in type 'Book | Book[]'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type '{ colour: string; }' is not assignable to type 'Cover'. | ||
Object literal may only specify known properties, but 'colour' does not exist in type 'Cover'. Did you mean to write 'color'? | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(37,25): error TS2304: Cannot find name 'IFoo'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(39,11): error TS2322: Type '{ name: string; }' is not assignable to type 'T'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(41,11): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T & { prop: boolean; }'. | ||
Type '{ name: string; prop: boolean; }' is not assignable to type 'T'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(43,43): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T | { prop: boolean; }'. | ||
Object literal may only specify known properties, and 'name' does not exist in type '{ prop: boolean; }'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(45,76): error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '{ name: string; } | (T & { prop: boolean; })'. | ||
Object literal may only specify known properties, and 'prop' does not exist in type '{ name: string; }'. | ||
tests/cases/compiler/objectLiteralExcessProperties.ts(49,44): error TS2322: Type '{ z: string; }' is not assignable to type 'object & { x: string; }'. | ||
Object literal may only specify known properties, and 'z' does not exist in type 'object & { x: string; }'. | ||
|
||
|
||
==== tests/cases/compiler/objectLiteralExcessProperties.ts (10 errors) ==== | ||
==== tests/cases/compiler/objectLiteralExcessProperties.ts (16 errors) ==== | ||
interface Book { | ||
foreword: string; | ||
} | ||
|
@@ -40,7 +50,7 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type | |
var b2: Book | string = { foreward: "nope" }; | ||
~~~~~~~~~~~~~~~~ | ||
!!! error TS2322: Type '{ foreward: string; }' is not assignable to type 'string | Book'. | ||
!!! error TS2322: Object literal may only specify known properties, and 'foreward' does not exist in type 'string | Book'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side note: in this or another PR, we should make these both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's probably most correct to have two separate sentences, as the subjects of the clauses are not well-connected. I call in @sandersn as our resident linguist to weigh in. |
||
!!! error TS2322: Object literal may only specify known properties, but 'foreward' does not exist in type 'Book'. Did you mean to write 'foreword'? | ||
|
||
var b3: Book | (Book[]) = [{ foreword: "hello" }, { forwards: "back" }]; | ||
~~~~~~~~~~~~~~~~ | ||
|
@@ -66,9 +76,9 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type | |
!!! error TS2322: Object literal may only specify known properties, and 'price' does not exist in type 'Book & Cover'. | ||
|
||
var b7: Book & number = { foreword: "hi", price: 10.99 }; | ||
~~~~~~~~~~~~ | ||
~~ | ||
!!! error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'Book & number'. | ||
!!! error TS2322: Object literal may only specify known properties, and 'price' does not exist in type 'Book & number'. | ||
!!! error TS2322: Type '{ foreword: string; price: number; }' is not assignable to type 'number'. | ||
|
||
var b8: Cover | Cover[] = { couleur : "non" }; | ||
~~~~~~~~~~~~~~~ | ||
|
@@ -91,4 +101,37 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(33,27): error TS2322: Type | |
!!! error TS2322: Type '{ colour: string; }' is not assignable to type 'Cover'. | ||
!!! error TS2322: Object literal may only specify known properties, but 'colour' does not exist in type 'Cover'. Did you mean to write 'color'? | ||
!!! related TS6501 tests/cases/compiler/objectLiteralExcessProperties.ts:28:5: The expected type comes from this index signature. | ||
|
||
// Repros inspired by #28752 | ||
|
||
function test<T extends IFoo>() { | ||
~~~~ | ||
!!! error TS2304: Cannot find name 'IFoo'. | ||
// No excess property checks on generic types | ||
const obj1: T = { name: "test" }; | ||
~~~~ | ||
!!! error TS2322: Type '{ name: string; }' is not assignable to type 'T'. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Side note: I've seen a couple issues opened where people don't really understand constrained generics well and are surprised an assignment like this fails and don't "get" the error. A little more elaboration could help here (ie, when assignment to a bare type parameter fails), like Unrelated to this PR, though. Just a remark. @DanielRosenwasser you agree? |
||
// No excess property checks on intersections involving generics | ||
const obj2: T & { prop: boolean } = { name: "test", prop: true }; | ||
~~~~ | ||
!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T & { prop: boolean; }'. | ||
!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T'. | ||
// Excess property checks only on non-generic parts of unions | ||
const obj3: T | { prop: boolean } = { name: "test", prop: true }; | ||
~~~~~~~~~~~~ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes sense in an assignment context, but declare function foo<T>(x: T | { prop: boolean }): T | boolean;
foo({prop: true, name: "test"}); // probably shouldn't be excess, trivially satisfies `T` for calls it seems a little jank, perhaps? The union case just seems presumptuous to me, I guess. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does the excess error happen before inference of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @weswigham As @jack-williams points out, there's no error in your example because we infer and substitute a type for |
||
!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type 'T | { prop: boolean; }'. | ||
!!! error TS2322: Object literal may only specify known properties, and 'name' does not exist in type '{ prop: boolean; }'. | ||
// Excess property checks only on non-generic parts of unions | ||
const obj4: T & { prop: boolean } | { name: string } = { name: "test", prop: true }; | ||
~~~~~~~~~~ | ||
!!! error TS2322: Type '{ name: string; prop: boolean; }' is not assignable to type '{ name: string; } | (T & { prop: boolean; })'. | ||
!!! error TS2322: Object literal may only specify known properties, and 'prop' does not exist in type '{ name: string; }'. | ||
// No excess property checks when union includes 'object' type | ||
const obj5: object | { x: string } = { z: 'abc' } | ||
// The 'object' type has no effect on intersections | ||
const obj6: object & { x: string } = { z: 'abc' } | ||
~~~~~~~~ | ||
!!! error TS2322: Type '{ z: string; }' is not assignable to type 'object & { x: string; }'. | ||
!!! error TS2322: Object literal may only specify known properties, and 'z' does not exist in type 'object & { x: string; }'. | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.