mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix check for get/set recommendation (#34885)
* Added more tests. * Accepted baselines. * Work better with any parameter type. * Accepted baselines. * Use the actual indexed expression. * Add tests that exhibit bad stringification. * Accepted baselines. * Short-circuit stringification on 'undefined'. * Accepted baselines. * Remove space. * Accepted baselines.
This commit is contained in:
@@ -11995,7 +11995,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression);
|
||||
const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression, indexType);
|
||||
if (suggestion !== undefined) {
|
||||
error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion);
|
||||
}
|
||||
@@ -23154,15 +23154,13 @@ namespace ts {
|
||||
return suggestion && symbolName(suggestion);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression): string | undefined {
|
||||
function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression, keyedType: Type): string | undefined {
|
||||
// check if object type has setter or getter
|
||||
const hasProp = (name: "set" | "get", argCount = 1) => {
|
||||
function hasProp(name: "set" | "get") {
|
||||
const prop = getPropertyOfObjectType(objectType, <__String>name);
|
||||
if (prop) {
|
||||
const s = getSingleCallSignature(getTypeOfSymbol(prop));
|
||||
if (s && getMinArgumentCount(s) === argCount && typeToString(getTypeAtPosition(s, 0)) === "string") {
|
||||
return true;
|
||||
}
|
||||
return !!s && getMinArgumentCount(s) >= 1 && isTypeAssignableTo(keyedType, getTypeAtPosition(s, 0));
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -23172,7 +23170,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let suggestion = tryGetPropertyAccessOrIdentifierToString(expr);
|
||||
let suggestion = tryGetPropertyAccessOrIdentifierToString(expr.expression);
|
||||
if (suggestion === undefined) {
|
||||
suggestion = suggestedMethod;
|
||||
}
|
||||
|
||||
@@ -4518,7 +4518,7 @@
|
||||
"category": "Error",
|
||||
"code": 7051
|
||||
},
|
||||
"Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}' ?": {
|
||||
"Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?": {
|
||||
"category": "Error",
|
||||
"code": 7052
|
||||
},
|
||||
|
||||
@@ -4244,9 +4244,12 @@ namespace ts {
|
||||
|
||||
export function tryGetPropertyAccessOrIdentifierToString(expr: Expression): string | undefined {
|
||||
if (isPropertyAccessExpression(expr)) {
|
||||
return tryGetPropertyAccessOrIdentifierToString(expr.expression) + "." + expr.name;
|
||||
const baseStr = tryGetPropertyAccessOrIdentifierToString(expr.expression);
|
||||
if (baseStr !== undefined) {
|
||||
return baseStr + "." + expr.name;
|
||||
}
|
||||
}
|
||||
if (isIdentifier(expr)) {
|
||||
else if (isIdentifier(expr)) {
|
||||
return unescapeLeadingUnderscores(expr.escapedText);
|
||||
}
|
||||
return undefined;
|
||||
|
||||
@@ -901,6 +901,7 @@ namespace ts.NavigationBar {
|
||||
return "<function>";
|
||||
}
|
||||
|
||||
// See also 'tryGetPropertyAccessOrIdentifierToString'
|
||||
function getCalledExpressionName(expr: Expression): string | undefined {
|
||||
if (isIdentifier(expr)) {
|
||||
return expr.text;
|
||||
|
||||
@@ -1,25 +1,43 @@
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(1,9): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'.
|
||||
Property 'hello' does not exist on type '{}'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(13,13): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'.
|
||||
Property 'hello' does not exist on type '{ set: (key: string) => string; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(19,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(26,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(49,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(50,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(52,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(57,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(59,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(65,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'.
|
||||
Property 'b' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(30,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(69,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'.
|
||||
Property 'c' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(72,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'.
|
||||
Property '[sym]' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(37,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(76,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'.
|
||||
Property '[NumEnum.a]' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(81,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'.
|
||||
Property '[StrEnum.b]' does not exist on type '{ a: number; }'.
|
||||
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: Type 'Dog' cannot be used as an index type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (12 errors) ====
|
||||
==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (30 errors) ====
|
||||
var a = {}["hello"];
|
||||
~~~~~~~~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'.
|
||||
@@ -31,10 +49,10 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053:
|
||||
};
|
||||
c['hello'];
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ?
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'?
|
||||
const foo = c['hello'];
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ?
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'?
|
||||
|
||||
var d = {
|
||||
set: (key: string) => 'foobar'
|
||||
@@ -44,19 +62,92 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053:
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'.
|
||||
!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: string) => string; }'.
|
||||
|
||||
var e = {
|
||||
set: (key: string) => 'foobar',
|
||||
get: (key: string) => 'foobar'
|
||||
};
|
||||
e['hello'] = 'modified';
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
e['hello'] += 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
e['hello'] ++;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ?
|
||||
{
|
||||
let e = {
|
||||
get: (key: string) => 'foobar',
|
||||
set: (key: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get'?
|
||||
e['hello'] = 'modified';
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
e['hello'] += 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
e['hello'] ++;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
get: (key: string) => 'foobar',
|
||||
set: (key: string, value: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get'?
|
||||
e['hello'] = 'modified';
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
e['hello'] += 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
e['hello'] ++;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
get: (key: "hello" | "world") => 'foobar',
|
||||
set: (key: "hello" | "world", value: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get'?
|
||||
e['hello'] = 'modified';
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
e['hello'] += 1;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
e['hello'] ++;
|
||||
~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'?
|
||||
}
|
||||
|
||||
{
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'];
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'?
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified';
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
}
|
||||
|
||||
{
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'];
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'?
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified';
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'?
|
||||
}
|
||||
|
||||
const o = { a: 0 };
|
||||
|
||||
@@ -93,4 +184,18 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053:
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'.
|
||||
!!! error TS7053: Property '[StrEnum.b]' does not exist on type '{ a: number; }'.
|
||||
|
||||
|
||||
interface MyMap<K, T> {
|
||||
get(key: K): T;
|
||||
set(key: K, value: T): void;
|
||||
}
|
||||
|
||||
interface Dog { bark(): void; }
|
||||
let rover: Dog = { bark() {} };
|
||||
|
||||
declare let map: MyMap<Dog, string>;
|
||||
map[rover] = "Rover";
|
||||
~~~~~
|
||||
!!! error TS2538: Type 'Dog' cannot be used as an index type.
|
||||
|
||||
@@ -13,13 +13,52 @@ var d = {
|
||||
};
|
||||
const bar = d['hello'];
|
||||
|
||||
var e = {
|
||||
set: (key: string) => 'foobar',
|
||||
get: (key: string) => 'foobar'
|
||||
};
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
{
|
||||
let e = {
|
||||
get: (key: string) => 'foobar',
|
||||
set: (key: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
get: (key: string) => 'foobar',
|
||||
set: (key: string, value: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
get: (key: "hello" | "world") => 'foobar',
|
||||
set: (key: "hello" | "world", value: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'];
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified';
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1;
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'];
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified';
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1;
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++;
|
||||
}
|
||||
|
||||
const o = { a: 0 };
|
||||
|
||||
@@ -41,6 +80,18 @@ o[numEnumKey];
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
let strEnumKey: StrEnum;
|
||||
o[strEnumKey];
|
||||
|
||||
|
||||
interface MyMap<K, T> {
|
||||
get(key: K): T;
|
||||
set(key: K, value: T): void;
|
||||
}
|
||||
|
||||
interface Dog { bark(): void; }
|
||||
let rover: Dog = { bark() {} };
|
||||
|
||||
declare let map: MyMap<Dog, string>;
|
||||
map[rover] = "Rover";
|
||||
|
||||
|
||||
//// [noImplicitAnyStringIndexerOnObject.js]
|
||||
@@ -55,13 +106,48 @@ var d = {
|
||||
set: function (key) { return 'foobar'; }
|
||||
};
|
||||
var bar = d['hello'];
|
||||
var e = {
|
||||
set: function (key) { return 'foobar'; },
|
||||
get: function (key) { return 'foobar'; }
|
||||
};
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello']++;
|
||||
{
|
||||
var e = {
|
||||
get: function (key) { return 'foobar'; },
|
||||
set: function (key) { return 'foobar'; }
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello']++;
|
||||
}
|
||||
{
|
||||
var e = {
|
||||
get: function (key) { return 'foobar'; },
|
||||
set: function (key, value) { return 'foobar'; }
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello']++;
|
||||
}
|
||||
{
|
||||
var e = {
|
||||
get: function (key) { return 'foobar'; },
|
||||
set: function (key, value) { return 'foobar'; }
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello']++;
|
||||
}
|
||||
{
|
||||
({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello'];
|
||||
({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello'] = 'modified';
|
||||
({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello'] += 1;
|
||||
({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello']++;
|
||||
}
|
||||
{
|
||||
({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello'];
|
||||
({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello'] = 'modified';
|
||||
({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello'] += 1;
|
||||
({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello']++;
|
||||
}
|
||||
var o = { a: 0 };
|
||||
o[k];
|
||||
o[k2];
|
||||
@@ -80,3 +166,5 @@ var StrEnum;
|
||||
})(StrEnum || (StrEnum = {}));
|
||||
var strEnumKey;
|
||||
o[strEnumKey];
|
||||
var rover = { bark: function () { } };
|
||||
map[rover] = "Rover";
|
||||
|
||||
@@ -34,77 +34,246 @@ const bar = d['hello'];
|
||||
>bar : Symbol(bar, Decl(noImplicitAnyStringIndexerOnObject.ts, 12, 5))
|
||||
>d : Symbol(d, Decl(noImplicitAnyStringIndexerOnObject.ts, 9, 3))
|
||||
|
||||
var e = {
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3))
|
||||
{
|
||||
let e = {
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5))
|
||||
|
||||
set: (key: string) => 'foobar',
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 9))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 8))
|
||||
get: (key: string) => 'foobar',
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 10))
|
||||
|
||||
get: (key: string) => 'foobar'
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 33))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 8))
|
||||
set: (key: string) => 'foobar'
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 35))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 17, 10))
|
||||
|
||||
};
|
||||
e['hello'] = 'modified';
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3))
|
||||
};
|
||||
e['hello'];
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5))
|
||||
|
||||
e['hello'] += 1;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3))
|
||||
e['hello'] = 'modified';
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5))
|
||||
|
||||
e['hello'] ++;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3))
|
||||
e['hello'] += 1;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5))
|
||||
|
||||
e['hello'] ++;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5))
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5))
|
||||
|
||||
get: (key: string) => 'foobar',
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 10))
|
||||
|
||||
set: (key: string, value: string) => 'foobar'
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 35))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 10))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 22))
|
||||
|
||||
};
|
||||
e['hello'];
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5))
|
||||
|
||||
e['hello'] = 'modified';
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5))
|
||||
|
||||
e['hello'] += 1;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5))
|
||||
|
||||
e['hello'] ++;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5))
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5))
|
||||
|
||||
get: (key: "hello" | "world") => 'foobar',
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 10))
|
||||
|
||||
set: (key: "hello" | "world", value: string) => 'foobar'
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 46))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 10))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 33))
|
||||
|
||||
};
|
||||
e['hello'];
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5))
|
||||
|
||||
e['hello'] = 'modified';
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5))
|
||||
|
||||
e['hello'] += 1;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5))
|
||||
|
||||
e['hello'] ++;
|
||||
>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5))
|
||||
}
|
||||
|
||||
{
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'];
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 4))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 11))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 35))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 42))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 54))
|
||||
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified';
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 4))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 11))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 35))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 42))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 54))
|
||||
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1;
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 4))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 11))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 35))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 42))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 54))
|
||||
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++;
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 4))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 11))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 35))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 42))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 54))
|
||||
}
|
||||
|
||||
{
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'];
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 4))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 4))
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 18))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 42))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 49))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 61))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 4))
|
||||
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified';
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 4))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 4))
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 18))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 42))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 49))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 61))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 4))
|
||||
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1;
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 4))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 4))
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 18))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 42))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 49))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 61))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 4))
|
||||
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++;
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 4))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 4))
|
||||
>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 11))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 18))
|
||||
>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 42))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 49))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 61))
|
||||
>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 4))
|
||||
}
|
||||
|
||||
const o = { a: 0 };
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 11))
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5))
|
||||
>a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 11))
|
||||
|
||||
declare const k: "a" | "b" | "c";
|
||||
>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 24, 13))
|
||||
>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 63, 13))
|
||||
|
||||
o[k];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 24, 13))
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5))
|
||||
>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 63, 13))
|
||||
|
||||
|
||||
declare const k2: "c";
|
||||
>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 13))
|
||||
>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 67, 13))
|
||||
|
||||
o[k2];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 13))
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5))
|
||||
>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 67, 13))
|
||||
|
||||
declare const sym : unique symbol;
|
||||
>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 31, 13))
|
||||
>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 13))
|
||||
|
||||
o[sym];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 31, 13))
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5))
|
||||
>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 13))
|
||||
|
||||
enum NumEnum { a, b }
|
||||
>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 32, 7))
|
||||
>a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 34, 14))
|
||||
>b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 34, 17))
|
||||
>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 7))
|
||||
>a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 73, 14))
|
||||
>b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 73, 17))
|
||||
|
||||
let numEnumKey: NumEnum;
|
||||
>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 35, 3))
|
||||
>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 32, 7))
|
||||
>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 74, 3))
|
||||
>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 7))
|
||||
|
||||
o[numEnumKey];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 35, 3))
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5))
|
||||
>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 74, 3))
|
||||
|
||||
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 36, 14))
|
||||
>a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 14))
|
||||
>b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 23))
|
||||
>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 14))
|
||||
>a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 78, 14))
|
||||
>b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 78, 23))
|
||||
|
||||
let strEnumKey: StrEnum;
|
||||
>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 40, 3))
|
||||
>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 36, 14))
|
||||
>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 79, 3))
|
||||
>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 14))
|
||||
|
||||
o[strEnumKey];
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5))
|
||||
>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 40, 3))
|
||||
>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5))
|
||||
>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 79, 3))
|
||||
|
||||
|
||||
interface MyMap<K, T> {
|
||||
>MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 80, 14))
|
||||
>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 16))
|
||||
>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 18))
|
||||
|
||||
get(key: K): T;
|
||||
>get : Symbol(MyMap.get, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 23))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 84, 6))
|
||||
>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 16))
|
||||
>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 18))
|
||||
|
||||
set(key: K, value: T): void;
|
||||
>set : Symbol(MyMap.set, Decl(noImplicitAnyStringIndexerOnObject.ts, 84, 17))
|
||||
>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 85, 6))
|
||||
>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 16))
|
||||
>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 85, 13))
|
||||
>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 18))
|
||||
}
|
||||
|
||||
interface Dog { bark(): void; }
|
||||
>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 86, 1))
|
||||
>bark : Symbol(Dog.bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 88, 15))
|
||||
|
||||
let rover: Dog = { bark() {} };
|
||||
>rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 89, 3))
|
||||
>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 86, 1))
|
||||
>bark : Symbol(bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 89, 18))
|
||||
|
||||
declare let map: MyMap<Dog, string>;
|
||||
>map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 91, 11))
|
||||
>MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 80, 14))
|
||||
>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 86, 1))
|
||||
|
||||
map[rover] = "Rover";
|
||||
>map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 91, 11))
|
||||
>rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 89, 3))
|
||||
|
||||
|
||||
@@ -52,42 +52,281 @@ const bar = d['hello'];
|
||||
>d : { set: (key: string) => string; }
|
||||
>'hello' : "hello"
|
||||
|
||||
var e = {
|
||||
>e : { set: (key: string) => string; get: (key: string) => string; }
|
||||
>{ set: (key: string) => 'foobar', get: (key: string) => 'foobar'} : { set: (key: string) => string; get: (key: string) => string; }
|
||||
{
|
||||
let e = {
|
||||
>e : { get: (key: string) => string; set: (key: string) => string; }
|
||||
>{ get: (key: string) => 'foobar', set: (key: string) => 'foobar' } : { get: (key: string) => string; set: (key: string) => string; }
|
||||
|
||||
set: (key: string) => 'foobar',
|
||||
>set : (key: string) => string
|
||||
>(key: string) => 'foobar' : (key: string) => string
|
||||
>key : string
|
||||
>'foobar' : "foobar"
|
||||
|
||||
get: (key: string) => 'foobar'
|
||||
get: (key: string) => 'foobar',
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'foobar' : (key: string) => string
|
||||
>key : string
|
||||
>'foobar' : "foobar"
|
||||
|
||||
};
|
||||
e['hello'] = 'modified';
|
||||
set: (key: string) => 'foobar'
|
||||
>set : (key: string) => string
|
||||
>(key: string) => 'foobar' : (key: string) => string
|
||||
>key : string
|
||||
>'foobar' : "foobar"
|
||||
|
||||
};
|
||||
e['hello'];
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: string) => string; set: (key: string) => string; }
|
||||
>'hello' : "hello"
|
||||
|
||||
e['hello'] = 'modified';
|
||||
>e['hello'] = 'modified' : "modified"
|
||||
>e['hello'] : any
|
||||
>e : { set: (key: string) => string; get: (key: string) => string; }
|
||||
>e : { get: (key: string) => string; set: (key: string) => string; }
|
||||
>'hello' : "hello"
|
||||
>'modified' : "modified"
|
||||
|
||||
e['hello'] += 1;
|
||||
e['hello'] += 1;
|
||||
>e['hello'] += 1 : any
|
||||
>e['hello'] : any
|
||||
>e : { set: (key: string) => string; get: (key: string) => string; }
|
||||
>e : { get: (key: string) => string; set: (key: string) => string; }
|
||||
>'hello' : "hello"
|
||||
>1 : 1
|
||||
|
||||
e['hello'] ++;
|
||||
e['hello'] ++;
|
||||
>e['hello'] ++ : number
|
||||
>e['hello'] : any
|
||||
>e : { set: (key: string) => string; get: (key: string) => string; }
|
||||
>e : { get: (key: string) => string; set: (key: string) => string; }
|
||||
>'hello' : "hello"
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
>e : { get: (key: string) => string; set: (key: string, value: string) => string; }
|
||||
>{ get: (key: string) => 'foobar', set: (key: string, value: string) => 'foobar' } : { get: (key: string) => string; set: (key: string, value: string) => string; }
|
||||
|
||||
get: (key: string) => 'foobar',
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'foobar' : (key: string) => string
|
||||
>key : string
|
||||
>'foobar' : "foobar"
|
||||
|
||||
set: (key: string, value: string) => 'foobar'
|
||||
>set : (key: string, value: string) => string
|
||||
>(key: string, value: string) => 'foobar' : (key: string, value: string) => string
|
||||
>key : string
|
||||
>value : string
|
||||
>'foobar' : "foobar"
|
||||
|
||||
};
|
||||
e['hello'];
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: string) => string; set: (key: string, value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
|
||||
e['hello'] = 'modified';
|
||||
>e['hello'] = 'modified' : "modified"
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: string) => string; set: (key: string, value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
>'modified' : "modified"
|
||||
|
||||
e['hello'] += 1;
|
||||
>e['hello'] += 1 : any
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: string) => string; set: (key: string, value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
>1 : 1
|
||||
|
||||
e['hello'] ++;
|
||||
>e['hello'] ++ : number
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: string) => string; set: (key: string, value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }
|
||||
>{ get: (key: "hello" | "world") => 'foobar', set: (key: "hello" | "world", value: string) => 'foobar' } : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }
|
||||
|
||||
get: (key: "hello" | "world") => 'foobar',
|
||||
>get : (key: "hello" | "world") => string
|
||||
>(key: "hello" | "world") => 'foobar' : (key: "hello" | "world") => string
|
||||
>key : "hello" | "world"
|
||||
>'foobar' : "foobar"
|
||||
|
||||
set: (key: "hello" | "world", value: string) => 'foobar'
|
||||
>set : (key: "hello" | "world", value: string) => string
|
||||
>(key: "hello" | "world", value: string) => 'foobar' : (key: "hello" | "world", value: string) => string
|
||||
>key : "hello" | "world"
|
||||
>value : string
|
||||
>'foobar' : "foobar"
|
||||
|
||||
};
|
||||
e['hello'];
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
|
||||
e['hello'] = 'modified';
|
||||
>e['hello'] = 'modified' : "modified"
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
>'modified' : "modified"
|
||||
|
||||
e['hello'] += 1;
|
||||
>e['hello'] += 1 : any
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
>1 : 1
|
||||
|
||||
e['hello'] ++;
|
||||
>e['hello'] ++ : number
|
||||
>e['hello'] : any
|
||||
>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }
|
||||
>'hello' : "hello"
|
||||
}
|
||||
|
||||
{
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'];
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>'hello' : "hello"
|
||||
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified';
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified' : "modified"
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>'hello' : "hello"
|
||||
>'modified' : "modified"
|
||||
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1;
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1 : any
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>'hello' : "hello"
|
||||
>1 : 1
|
||||
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++;
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++ : number
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any
|
||||
>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>'hello' : "hello"
|
||||
}
|
||||
|
||||
{
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'];
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>'hello' : "hello"
|
||||
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified';
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified' : "modified"
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>'hello' : "hello"
|
||||
>'modified' : "modified"
|
||||
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1;
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1 : any
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>'hello' : "hello"
|
||||
>1 : 1
|
||||
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++;
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++ : number
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; }
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>get : (key: string) => string
|
||||
>(key: string) => 'hello' : (key: string) => string
|
||||
>key : string
|
||||
>'hello' : "hello"
|
||||
>set : (key: string, value: string) => void
|
||||
>(key: string, value: string) => {} : (key: string, value: string) => void
|
||||
>key : string
|
||||
>value : string
|
||||
>foo : { get: (key: string) => string; set: (key: string, value: string) => void; }
|
||||
>'hello' : "hello"
|
||||
}
|
||||
|
||||
const o = { a: 0 };
|
||||
>o : { a: number; }
|
||||
@@ -149,3 +388,33 @@ o[strEnumKey];
|
||||
>o : { a: number; }
|
||||
>strEnumKey : StrEnum
|
||||
|
||||
|
||||
interface MyMap<K, T> {
|
||||
get(key: K): T;
|
||||
>get : (key: K) => T
|
||||
>key : K
|
||||
|
||||
set(key: K, value: T): void;
|
||||
>set : (key: K, value: T) => void
|
||||
>key : K
|
||||
>value : T
|
||||
}
|
||||
|
||||
interface Dog { bark(): void; }
|
||||
>bark : () => void
|
||||
|
||||
let rover: Dog = { bark() {} };
|
||||
>rover : Dog
|
||||
>{ bark() {} } : { bark(): void; }
|
||||
>bark : () => void
|
||||
|
||||
declare let map: MyMap<Dog, string>;
|
||||
>map : MyMap<Dog, string>
|
||||
|
||||
map[rover] = "Rover";
|
||||
>map[rover] = "Rover" : "Rover"
|
||||
>map[rover] : any
|
||||
>map : MyMap<Dog, string>
|
||||
>rover : Dog
|
||||
>"Rover" : "Rover"
|
||||
|
||||
|
||||
@@ -14,13 +14,52 @@ var d = {
|
||||
};
|
||||
const bar = d['hello'];
|
||||
|
||||
var e = {
|
||||
set: (key: string) => 'foobar',
|
||||
get: (key: string) => 'foobar'
|
||||
};
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
{
|
||||
let e = {
|
||||
get: (key: string) => 'foobar',
|
||||
set: (key: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
get: (key: string) => 'foobar',
|
||||
set: (key: string, value: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
let e = {
|
||||
get: (key: "hello" | "world") => 'foobar',
|
||||
set: (key: "hello" | "world", value: string) => 'foobar'
|
||||
};
|
||||
e['hello'];
|
||||
e['hello'] = 'modified';
|
||||
e['hello'] += 1;
|
||||
e['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'];
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified';
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1;
|
||||
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++;
|
||||
}
|
||||
|
||||
{
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'];
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified';
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1;
|
||||
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++;
|
||||
}
|
||||
|
||||
const o = { a: 0 };
|
||||
|
||||
@@ -42,3 +81,15 @@ o[numEnumKey];
|
||||
enum StrEnum { a = "a", b = "b" }
|
||||
let strEnumKey: StrEnum;
|
||||
o[strEnumKey];
|
||||
|
||||
|
||||
interface MyMap<K, T> {
|
||||
get(key: K): T;
|
||||
set(key: K, value: T): void;
|
||||
}
|
||||
|
||||
interface Dog { bark(): void; }
|
||||
let rover: Dog = { bark() {} };
|
||||
|
||||
declare let map: MyMap<Dog, string>;
|
||||
map[rover] = "Rover";
|
||||
|
||||
Reference in New Issue
Block a user