Only allow excess numeric properties w/numeric indexers

Previously, having a numeric indexer on a target type meant that excess
object property checking would allow any property. Now only numeric
properties are allowed.
This commit is contained in:
Nathan Shively-Sanders 2016-05-25 10:12:16 -07:00
parent d7e30f099d
commit 642d6d5407
4 changed files with 31 additions and 4 deletions

View file

@ -6034,11 +6034,14 @@ namespace ts {
function isKnownProperty(type: Type, name: string): boolean {
if (type.flags & TypeFlags.ObjectType) {
const resolved = resolveStructuredTypeMembers(type);
if ((relation === assignableRelation || relation === comparableRelation) &&
(type === globalObjectType || isEmptyObjectType(resolved)) ||
resolved.stringIndexInfo || resolved.numberIndexInfo || getPropertyOfType(type, name)) {
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
resolved.stringIndexInfo ||
getPropertyOfType(type, name)) {
return true;
}
if (resolved.numberIndexInfo) {
return isNumericLiteralName(name);
}
}
else if (type.flags & TypeFlags.UnionOrIntersection) {
for (const t of (<UnionOrIntersectionType>type).types) {

View file

@ -15,9 +15,13 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(19,57): error TS2322: Type
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(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 (7 errors) ====
==== tests/cases/compiler/objectLiteralExcessProperties.ts (9 errors) ====
interface Book {
foreword: string;
}
@ -63,4 +67,14 @@ tests/cases/compiler/objectLiteralExcessProperties.ts(21,43): error TS2322: Type
~~~~~~~~~~~~
!!! 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'.
var b8: Cover | Cover[] = { couleur : "non" };
~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ couleur: string; }' is not assignable to type 'Cover | Cover[]'.
!!! error TS2322: Object literal may only specify known properties, and 'couleur' does not exist in type 'Cover | Cover[]'.
var b9: Book | Book[] = { forewarned: "still no" };
~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type '{ forewarned: string; }' is not assignable to type 'Book | Book[]'.
!!! error TS2322: Object literal may only specify known properties, and 'forewarned' does not exist in type 'Book | Book[]'.

View file

@ -20,6 +20,10 @@ var b5: Book & Cover = { foreward: "hi", color: "blue" };
var b6: Book & Cover = { foreword: "hi", color: "blue", price: 10.99 };
var b7: Book & number = { foreword: "hi", price: 10.99 };
var b8: Cover | Cover[] = { couleur : "non" };
var b9: Book | Book[] = { forewarned: "still no" };
//// [objectLiteralExcessProperties.js]
@ -30,3 +34,5 @@ var b4 = { foreword: "hi", colour: "blue" };
var b5 = { foreward: "hi", color: "blue" };
var b6 = { foreword: "hi", color: "blue", price: 10.99 };
var b7 = { foreword: "hi", price: 10.99 };
var b8 = { couleur: "non" };
var b9 = { forewarned: "still no" };

View file

@ -19,3 +19,7 @@ var b5: Book & Cover = { foreward: "hi", color: "blue" };
var b6: Book & Cover = { foreword: "hi", color: "blue", price: 10.99 };
var b7: Book & number = { foreword: "hi", price: 10.99 };
var b8: Cover | Cover[] = { couleur : "non" };
var b9: Book | Book[] = { forewarned: "still no" };