mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Merge pull request #12671 from Microsoft/property-access-for-string-index-sigs
Property access for string index signatures
This commit is contained in:
@@ -12444,6 +12444,10 @@ namespace ts {
|
||||
}
|
||||
const prop = getPropertyOfType(apparentType, right.text);
|
||||
if (!prop) {
|
||||
const stringIndexType = getIndexTypeOfType(apparentType, IndexKind.String);
|
||||
if (stringIndexType) {
|
||||
return stringIndexType;
|
||||
}
|
||||
if (right.text && !checkAndReportErrorForExtendingInterface(node)) {
|
||||
reportNonexistentProperty(right, type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType ? apparentType : type);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ let computed2 = 'a';
|
||||
var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
|
||||
({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o);
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
|
||||
|
||||
//// [objectRest.js]
|
||||
@@ -89,6 +89,6 @@ var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __re
|
||||
(_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""]));
|
||||
var noContextualType = (_a) => {
|
||||
var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]);
|
||||
return aNumber + notEmptyObject['anythingGoes'];
|
||||
return aNumber + notEmptyObject.anythingGoes;
|
||||
};
|
||||
var _d, _f, _j, _k;
|
||||
|
||||
@@ -191,7 +191,7 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
|
||||
>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 42, 51))
|
||||
>o : Symbol(o, Decl(objectRest.ts, 0, 3), Decl(objectRest.ts, 42, 51))
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
>noContextualType : Symbol(noContextualType, Decl(objectRest.ts, 45, 3))
|
||||
>aNumber : Symbol(aNumber, Decl(objectRest.ts, 45, 25))
|
||||
>notEmptyObject : Symbol(notEmptyObject, Decl(objectRest.ts, 45, 39))
|
||||
|
||||
@@ -217,15 +217,15 @@ var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
|
||||
>o : { a: number; b: string; }
|
||||
>o : { a: number; b: string; }
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
>noContextualType : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any
|
||||
>({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'] : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any
|
||||
>({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes : ({aNumber, ...notEmptyObject}: { [x: string]: any; aNumber?: number; }) => any
|
||||
>aNumber : number
|
||||
>12 : 12
|
||||
>notEmptyObject : { [x: string]: any; }
|
||||
>aNumber + notEmptyObject['anythingGoes'] : any
|
||||
>aNumber + notEmptyObject.anythingGoes : any
|
||||
>aNumber : number
|
||||
>notEmptyObject['anythingGoes'] : any
|
||||
>notEmptyObject.anythingGoes : any
|
||||
>notEmptyObject : { [x: string]: any; }
|
||||
>'anythingGoes' : "anythingGoes"
|
||||
>anythingGoes : any
|
||||
|
||||
|
||||
@@ -7,10 +7,9 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(11,30): error TS7008: M
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(11,33): error TS7008: Member 'y' implicitly has an 'any' type.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(12,17): error TS2700: Rest types may only be created from object types.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: The target of an object rest assignment must be a variable or a property access.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(19,90): error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/objectRestNegative.ts (8 errors) ====
|
||||
==== tests/cases/conformance/types/rest/objectRestNegative.ts (7 errors) ====
|
||||
let o = { a: 1, b: 'no' };
|
||||
var { ...mustBeLast, a } = o;
|
||||
~~~~~~~~~~
|
||||
@@ -44,8 +43,4 @@ tests/cases/conformance/types/rest/objectRestNegative.ts(19,90): error TS2339: P
|
||||
({a, ...rest.b + rest.b} = o);
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2339: Property 'anythingGoes' does not exist on type '{ [x: string]: any; }'.
|
||||
|
||||
@@ -16,8 +16,6 @@ function generic<T extends { x, y }>(t: T) {
|
||||
|
||||
let rest: { b: string }
|
||||
({a, ...rest.b + rest.b} = o);
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
|
||||
|
||||
//// [objectRestNegative.js]
|
||||
@@ -44,7 +42,3 @@ function generic(t) {
|
||||
}
|
||||
var rest;
|
||||
(a = o.a, o, rest.b + rest.b = __rest(o, ["a"]));
|
||||
var noContextualType = function (_a) {
|
||||
var _b = _a.aNumber, aNumber = _b === void 0 ? 12 : _b, notEmptyObject = __rest(_a, ["aNumber"]);
|
||||
return aNumber + notEmptyObject.anythingGoes;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts(10,7): error TS2339: Property 'nope' does not exist on type 'Empty'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignature.ts (1 errors) ====
|
||||
interface Flags { [name: string]: boolean };
|
||||
let flags: Flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
|
||||
interface Empty { }
|
||||
let empty: Empty;
|
||||
empty.nope;
|
||||
~~~~
|
||||
!!! error TS2339: Property 'nope' does not exist on type 'Empty'.
|
||||
empty["that's ok"];
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//// [propertyAccessStringIndexSignature.ts]
|
||||
interface Flags { [name: string]: boolean };
|
||||
let flags: Flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
|
||||
interface Empty { }
|
||||
let empty: Empty;
|
||||
empty.nope;
|
||||
empty["that's ok"];
|
||||
|
||||
|
||||
//// [propertyAccessStringIndexSignature.js]
|
||||
;
|
||||
var flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
var empty;
|
||||
empty.nope;
|
||||
empty["that's ok"];
|
||||
@@ -0,0 +1,21 @@
|
||||
tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts(10,7): error TS2339: Property 'nope' does not exist on type 'Empty'.
|
||||
tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts(11,1): error TS7017: Element implicitly has an 'any' type because type 'Empty' has no index signature.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/propertyAccess/propertyAccessStringIndexSignatureNoImplicitAny.ts (2 errors) ====
|
||||
interface Flags { [name: string]: boolean }
|
||||
let flags: Flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
|
||||
interface Empty { }
|
||||
let empty: Empty;
|
||||
empty.nope;
|
||||
~~~~
|
||||
!!! error TS2339: Property 'nope' does not exist on type 'Empty'.
|
||||
empty["not allowed either"];
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7017: Element implicitly has an 'any' type because type 'Empty' has no index signature.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
//// [propertyAccessStringIndexSignatureNoImplicitAny.ts]
|
||||
interface Flags { [name: string]: boolean }
|
||||
let flags: Flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
|
||||
interface Empty { }
|
||||
let empty: Empty;
|
||||
empty.nope;
|
||||
empty["not allowed either"];
|
||||
|
||||
|
||||
//// [propertyAccessStringIndexSignatureNoImplicitAny.js]
|
||||
var flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
var empty;
|
||||
empty.nope;
|
||||
empty["not allowed either"];
|
||||
@@ -0,0 +1,11 @@
|
||||
interface Flags { [name: string]: boolean };
|
||||
let flags: Flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
|
||||
interface Empty { }
|
||||
let empty: Empty;
|
||||
empty.nope;
|
||||
empty["that's ok"];
|
||||
@@ -0,0 +1,12 @@
|
||||
// @noImplicitAny: true
|
||||
interface Flags { [name: string]: boolean }
|
||||
let flags: Flags;
|
||||
flags.b;
|
||||
flags.f;
|
||||
flags.isNotNecessarilyNeverFalse;
|
||||
flags['this is fine'];
|
||||
|
||||
interface Empty { }
|
||||
let empty: Empty;
|
||||
empty.nope;
|
||||
empty["not allowed either"];
|
||||
@@ -44,4 +44,4 @@ let computed2 = 'a';
|
||||
var { [computed]: stillNotGreat, [computed2]: soSo, ...o } = o;
|
||||
({ [computed]: stillNotGreat, [computed2]: soSo, ...o } = o);
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject['anythingGoes'];
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
|
||||
@@ -16,5 +16,3 @@ function generic<T extends { x, y }>(t: T) {
|
||||
|
||||
let rest: { b: string }
|
||||
({a, ...rest.b + rest.b} = o);
|
||||
|
||||
var noContextualType = ({ aNumber = 12, ...notEmptyObject }) => aNumber + notEmptyObject.anythingGoes;
|
||||
|
||||
Reference in New Issue
Block a user