diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6edba58cb1167..2a5b7e4409c83 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -188,6 +188,11 @@ namespace ts { } if (node.name.kind === SyntaxKind.ComputedPropertyName) { const nameExpression = (node.name).expression; + // treat computed property names where expression is string/numeric literal as just string/numeric literal + if (isStringOrNumericLiteral(nameExpression.kind)) { + return (nameExpression).text; + } + Debug.assert(isWellKnownSymbolSyntactically(nameExpression)); return getPropertyNameForKnownSymbolName((nameExpression).name.text); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 993742a71e1ce..8b3b0417d5ddc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2337,6 +2337,26 @@ namespace ts { return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node); } + function getTextOfPropertyName(name: PropertyName): string { + switch (name.kind) { + case SyntaxKind.Identifier: + return (name).text; + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + return (name).text; + case SyntaxKind.ComputedPropertyName: + if (isStringOrNumericLiteral((name).expression.kind)) { + return ((name).expression).text; + } + } + + return undefined; + } + + function isComputedNonLiteralName(name: PropertyName): boolean { + return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((name).expression.kind); + } + // Return the inferred type for a binding element function getTypeForBindingElement(declaration: BindingElement): Type { const pattern = declaration.parent; @@ -2359,10 +2379,17 @@ namespace ts { if (pattern.kind === SyntaxKind.ObjectBindingPattern) { // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) const name = declaration.propertyName || declaration.name; + if (isComputedNonLiteralName(name)) { + // computed properties with non-literal names are treated as 'any' + return anyType; + } + // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature, // or otherwise the type of the string index signature. - type = getTypeOfPropertyOfType(parentType, name.text) || - isNumericLiteralName(name.text) && getIndexTypeOfType(parentType, IndexKind.Number) || + const text = getTextOfPropertyName(name); + + type = getTypeOfPropertyOfType(parentType, text) || + isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) || getIndexTypeOfType(parentType, IndexKind.String); if (!type) { error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), declarationNameToString(name)); @@ -2473,10 +2500,18 @@ namespace ts { // Return the type implied by an object binding pattern function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type { const members: SymbolTable = {}; + let hasComputedProperties = false; forEach(pattern.elements, e => { - const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0); const name = e.propertyName || e.name; - const symbol = createSymbol(flags, name.text); + if (isComputedNonLiteralName(name)) { + // do not include computed properties in the implied type + hasComputedProperties = true; + return; + } + + const text = getTextOfPropertyName(name); + const flags = SymbolFlags.Property | SymbolFlags.Transient | (e.initializer ? SymbolFlags.Optional : 0); + const symbol = createSymbol(flags, text); symbol.type = getTypeFromBindingElement(e, includePatternInType); symbol.bindingElement = e; members[symbol.name] = symbol; @@ -2485,6 +2520,9 @@ namespace ts { if (includePatternInType) { result.pattern = pattern; } + if (hasComputedProperties) { + result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties; + } return result; } @@ -4977,7 +5015,7 @@ namespace ts { } function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { - if (someConstituentTypeHasKind(target, TypeFlags.ObjectType)) { + if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && someConstituentTypeHasKind(target, TypeFlags.ObjectType)) { for (const prop of getPropertiesOfObjectType(source)) { if (!isKnownProperty(target, prop.name)) { if (reportErrors) { @@ -7395,6 +7433,7 @@ namespace ts { (contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression); let typeFlags: TypeFlags = 0; + let patternWithComputedProperties = false; for (const memberDecl of node.properties) { let member = memberDecl.symbol; if (memberDecl.kind === SyntaxKind.PropertyAssignment || @@ -7422,8 +7461,11 @@ namespace ts { if (isOptional) { prop.flags |= SymbolFlags.Optional; } + if (hasDynamicName(memberDecl)) { + patternWithComputedProperties = true; + } } - else if (contextualTypeHasPattern) { + else if (contextualTypeHasPattern && !(contextualType.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties)) { // If object literal is contextually typed by the implied type of a binding pattern, and if the // binding pattern specifies a default value for the property, make the property optional. const impliedProp = getPropertyOfType(contextualType, member.name); @@ -7480,7 +7522,7 @@ namespace ts { const numberIndexType = getIndexType(IndexKind.Number); const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType); const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshObjectLiteral; - result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags); + result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0); if (inDestructuringPattern) { result.pattern = node; } @@ -9999,19 +10041,27 @@ namespace ts { const properties = node.properties; for (const p of properties) { if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) { - // TODO(andersh): Computed property support - const name = (p).name; + const name = (p).name; + if (name.kind === SyntaxKind.ComputedPropertyName) { + checkComputedPropertyName(name); + } + if (isComputedNonLiteralName(name)) { + continue; + } + + const text = getTextOfPropertyName(name); const type = isTypeAny(sourceType) ? sourceType - : getTypeOfPropertyOfType(sourceType, name.text) || - isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) || + : getTypeOfPropertyOfType(sourceType, text) || + isNumericLiteralName(text) && getIndexTypeOfType(sourceType, IndexKind.Number) || getIndexTypeOfType(sourceType, IndexKind.String); if (type) { if (p.kind === SyntaxKind.ShorthandPropertyAssignment) { checkDestructuringAssignment(p, type); } else { - checkDestructuringAssignment((p).initializer || name, type); + // non-shorthand property assignments should always have initializers + checkDestructuringAssignment((p).initializer, type); } } else { @@ -12130,6 +12180,14 @@ namespace ts { checkExpressionCached(node.initializer); } } + + if (node.kind === SyntaxKind.BindingElement) { + // check computed properties inside property names of binding elements + if (node.propertyName && node.propertyName.kind === SyntaxKind.ComputedPropertyName) { + checkComputedPropertyName(node.propertyName); + } + } + // For a binding pattern, check contained binding elements if (isBindingPattern(node.name)) { forEach((node.name).elements, checkSourceElement); @@ -13234,11 +13292,14 @@ namespace ts { const enumIsConst = isConst(node); for (const member of node.members) { - if (member.name.kind === SyntaxKind.ComputedPropertyName) { + if (isComputedNonLiteralName(member.name)) { error(member.name, Diagnostics.Computed_property_names_are_not_allowed_in_enums); } - else if (isNumericLiteralName((member.name).text)) { - error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); + else { + const text = getTextOfPropertyName(member.name); + if (isNumericLiteralName(text)) { + error(member.name, Diagnostics.An_enum_member_cannot_have_a_numeric_name); + } } const previousEnumMemberIsNonConstant = autoValue === undefined; @@ -15682,7 +15743,7 @@ namespace ts { } function checkGrammarForNonSymbolComputedProperty(node: DeclarationName, message: DiagnosticMessage) { - if (node.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically((node).expression)) { + if (isDynamicName(node)) { return grammarErrorOnNode(node, message); } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 464bd51a91d61..057be9e0b9604 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4167,15 +4167,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi return node; } - function createPropertyAccessForDestructuringProperty(object: Expression, propName: Identifier | LiteralExpression): Expression { - // We create a synthetic copy of the identifier in order to avoid the rewriting that might - // otherwise occur when the identifier is emitted. - const syntheticName = createSynthesizedNode(propName.kind); - syntheticName.text = propName.text; - if (syntheticName.kind !== SyntaxKind.Identifier) { - return createElementAccessExpression(object, syntheticName); - } - return createPropertyAccessExpression(object, syntheticName); + function createPropertyAccessForDestructuringProperty(object: Expression, propName: PropertyName): Expression { + let index: Expression; + const nameIsComputed = propName.kind === SyntaxKind.ComputedPropertyName; + if (nameIsComputed) { + index = ensureIdentifier((propName).expression, /* reuseIdentifierExpression */ false); + } + else { + // We create a synthetic copy of the identifier in order to avoid the rewriting that might + // otherwise occur when the identifier is emitted. + index = createSynthesizedNode(propName.kind); + (index).text = (propName).text; + } + + return !nameIsComputed && index.kind === SyntaxKind.Identifier + ? createPropertyAccessExpression(object, index) + : createElementAccessExpression(object, index); } function createSliceCall(value: Expression, sliceIndex: number): CallExpression { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ab06b12318b77..2e539097e24ff 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1069,7 +1069,7 @@ namespace ts { token === SyntaxKind.NumericLiteral; } - function parsePropertyNameWorker(allowComputedPropertyNames: boolean): DeclarationName { + function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName { if (token === SyntaxKind.StringLiteral || token === SyntaxKind.NumericLiteral) { return parseLiteralNode(/*internName*/ true); } @@ -1079,7 +1079,7 @@ namespace ts { return parseIdentifierName(); } - function parsePropertyName(): DeclarationName { + function parsePropertyName(): PropertyName { return parsePropertyNameWorker(/*allowComputedPropertyNames:*/ true); } @@ -1189,7 +1189,7 @@ namespace ts { case ParsingContext.ObjectLiteralMembers: return token === SyntaxKind.OpenBracketToken || token === SyntaxKind.AsteriskToken || isLiteralPropertyName(); case ParsingContext.ObjectBindingElements: - return isLiteralPropertyName(); + return token === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); case ParsingContext.HeritageClauseElement: // If we see { } then only consume it as an expression if it is followed by , or { // That way we won't consume the body of a class in its heritage clause. @@ -4568,7 +4568,6 @@ namespace ts { function parseObjectBindingElement(): BindingElement { const node = createNode(SyntaxKind.BindingElement); - // TODO(andersh): Handle computed properties const tokenIsIdentifier = isIdentifier(); const propertyName = parsePropertyName(); if (tokenIsIdentifier && token !== SyntaxKind.ColonToken) { @@ -4576,7 +4575,7 @@ namespace ts { } else { parseExpected(SyntaxKind.ColonToken); - node.propertyName = propertyName; + node.propertyName = propertyName; node.name = parseIdentifierOrPattern(); } node.initializer = parseBindingElementInitializer(/*inParameter*/ false); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f536a1e469307..4ed64b07f17e8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -491,6 +491,7 @@ namespace ts { export type EntityName = Identifier | QualifiedName; + export type PropertyName = Identifier | LiteralExpression | ComputedPropertyName; export type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern; export interface Declaration extends Node { @@ -543,7 +544,7 @@ namespace ts { // SyntaxKind.BindingElement export interface BindingElement extends Declaration { - propertyName?: Identifier; // Binding property name (in object binding pattern) + propertyName?: PropertyName; // Binding property name (in object binding pattern) dotDotDotToken?: Node; // Present on rest binding element name: Identifier | BindingPattern; // Declared binding element name initializer?: Expression; // Optional initializer @@ -587,7 +588,7 @@ namespace ts { // SyntaxKind.ShorthandPropertyAssignment // SyntaxKind.EnumMember export interface VariableLikeDeclaration extends Declaration { - propertyName?: Identifier; + propertyName?: PropertyName; dotDotDotToken?: Node; name: DeclarationName; questionToken?: Node; @@ -1821,6 +1822,7 @@ namespace ts { ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6 ThisType = 0x02000000, // This type + ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties /* @internal */ Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index aecf8ab76ba9a..4335df47670b1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1427,6 +1427,10 @@ namespace ts { return isFunctionLike(node) && (node.flags & NodeFlags.Async) !== 0 && !isAccessor(node); } + export function isStringOrNumericLiteral(kind: SyntaxKind): boolean { + return kind === SyntaxKind.StringLiteral || kind === SyntaxKind.NumericLiteral; + } + /** * A declaration has a dynamic name if both of the following are true: * 1. The declaration has a computed property name @@ -1435,9 +1439,13 @@ namespace ts { * Symbol. */ export function hasDynamicName(declaration: Declaration): boolean { - return declaration.name && - declaration.name.kind === SyntaxKind.ComputedPropertyName && - !isWellKnownSymbolSyntactically((declaration.name).expression); + return declaration.name && isDynamicName(declaration.name); + } + + export function isDynamicName(name: DeclarationName): boolean { + return name.kind === SyntaxKind.ComputedPropertyName && + !isStringOrNumericLiteral((name).expression.kind) && + !isWellKnownSymbolSyntactically((name).expression); } /** diff --git a/src/services/services.ts b/src/services/services.ts index 1672e4ad4ff22..a2ffd2d991e74 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3814,7 +3814,10 @@ namespace ts { let existingName: string; if (m.kind === SyntaxKind.BindingElement && (m).propertyName) { - existingName = (m).propertyName.text; + // include only identifiers in completion list + if ((m).propertyName.kind === SyntaxKind.Identifier) { + existingName = ((m).propertyName).text + } } else { // TODO(jfreeman): Account for computed property name diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt b/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt new file mode 100644 index 0000000000000..dc536e544b23f --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring1.errors.txt @@ -0,0 +1,52 @@ +tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,12): error TS2339: Property 'toExponential' does not exist on type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,4): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,5): error TS2365: Operator '+' cannot be applied to types 'number' and '{}'. + + +==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (4 errors) ==== + // destructuring in variable declarations + let foo = "bar"; + let {[foo]: bar} = {bar: "bar"}; + + let {["bar"]: bar2} = {bar: "bar"}; + + let foo2 = () => "bar"; + let {[foo2()]: bar3} = {bar: "bar"}; + + let [{[foo]: bar4}] = [{bar: "bar"}]; + let [{[foo2()]: bar5}] = [{bar: "bar"}]; + + function f1({["bar"]: x}: { bar: number }) {} + function f2({[foo]: x}: { bar: number }) {} + function f3({[foo2()]: x}: { bar: number }) {} + function f4([{[foo]: x}]: [{ bar: number }]) {} + function f5([{[foo2()]: x}]: [{ bar: number }]) {} + + // report errors on type errors in computed properties used in destructuring + let [{[foo()]: bar6}] = [{bar: "bar"}]; + ~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}]; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'toExponential' does not exist on type 'string'. + + // destructuring assignment + ({[foo]: bar} = {bar: "bar"}); + + ({["bar"]: bar2} = {bar: "bar"}); + + ({[foo2()]: bar3} = {bar: "bar"}); + + [{[foo]: bar4}] = [{bar: "bar"}]; + [{[foo2()]: bar5}] = [{bar: "bar"}]; + + [{[foo()]: bar4}] = [{bar: "bar"}]; + ~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + [{[(1 + {})]: bar4}] = [{bar: "bar"}]; + ~~~~~~ +!!! error TS2365: Operator '+' cannot be applied to types 'number' and '{}'. + + + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1.js b/tests/baselines/reference/computedPropertiesInDestructuring1.js new file mode 100644 index 0000000000000..0bc4286ed7b79 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring1.js @@ -0,0 +1,75 @@ +//// [computedPropertiesInDestructuring1.ts] +// destructuring in variable declarations +let foo = "bar"; +let {[foo]: bar} = {bar: "bar"}; + +let {["bar"]: bar2} = {bar: "bar"}; + +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {bar: "bar"}; + +let [{[foo]: bar4}] = [{bar: "bar"}]; +let [{[foo2()]: bar5}] = [{bar: "bar"}]; + +function f1({["bar"]: x}: { bar: number }) {} +function f2({[foo]: x}: { bar: number }) {} +function f3({[foo2()]: x}: { bar: number }) {} +function f4([{[foo]: x}]: [{ bar: number }]) {} +function f5([{[foo2()]: x}]: [{ bar: number }]) {} + +// report errors on type errors in computed properties used in destructuring +let [{[foo()]: bar6}] = [{bar: "bar"}]; +let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}]; + +// destructuring assignment +({[foo]: bar} = {bar: "bar"}); + +({["bar"]: bar2} = {bar: "bar"}); + +({[foo2()]: bar3} = {bar: "bar"}); + +[{[foo]: bar4}] = [{bar: "bar"}]; +[{[foo2()]: bar5}] = [{bar: "bar"}]; + +[{[foo()]: bar4}] = [{bar: "bar"}]; +[{[(1 + {})]: bar4}] = [{bar: "bar"}]; + + + + +//// [computedPropertiesInDestructuring1.js] +// destructuring in variable declarations +var foo = "bar"; +var _a = foo, bar = { bar: "bar" }[_a]; +var _b = "bar", bar2 = { bar: "bar" }[_b]; +var foo2 = function () { return "bar"; }; +var _c = foo2(), bar3 = { bar: "bar" }[_c]; +var _d = foo, bar4 = [{ bar: "bar" }][0][_d]; +var _e = foo2(), bar5 = [{ bar: "bar" }][0][_e]; +function f1(_a) { + var _b = "bar", x = _a[_b]; +} +function f2(_a) { + var _b = foo, x = _a[_b]; +} +function f3(_a) { + var _b = foo2(), x = _a[_b]; +} +function f4(_a) { + var _b = foo, x = _a[0][_b]; +} +function f5(_a) { + var _b = foo2(), x = _a[0][_b]; +} +// report errors on type errors in computed properties used in destructuring +var _f = foo(), bar6 = [{ bar: "bar" }][0][_f]; +var _g = foo.toExponential(), bar7 = [{ bar: "bar" }][0][_g]; +// destructuring assignment +(_h = { bar: "bar" }, _j = foo, bar = _h[_j], _h); +(_k = { bar: "bar" }, _l = "bar", bar2 = _k[_l], _k); +(_m = { bar: "bar" }, _o = foo2(), bar3 = _m[_o], _m); +_p = foo, bar4 = [{ bar: "bar" }][0][_p]; +_q = foo2(), bar5 = [{ bar: "bar" }][0][_q]; +_r = foo(), bar4 = [{ bar: "bar" }][0][_r]; +_s = (1 + {}), bar4 = [{ bar: "bar" }][0][_s]; +var _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt new file mode 100644 index 0000000000000..96ab892d1b953 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.errors.txt @@ -0,0 +1,51 @@ +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,12): error TS2339: Property 'toExponential' does not exist on type 'string'. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,4): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,5): error TS2365: Operator '+' cannot be applied to types 'number' and '{}'. + + +==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (4 errors) ==== + // destructuring in variable declarations + let foo = "bar"; + let {[foo]: bar} = {bar: "bar"}; + + let {["bar"]: bar2} = {bar: "bar"}; + let {[11]: bar2_1} = {11: "bar"}; + + let foo2 = () => "bar"; + let {[foo2()]: bar3} = {bar: "bar"}; + + let [{[foo]: bar4}] = [{bar: "bar"}]; + let [{[foo2()]: bar5}] = [{bar: "bar"}]; + + function f1({["bar"]: x}: { bar: number }) {} + function f2({[foo]: x}: { bar: number }) {} + function f3({[foo2()]: x}: { bar: number }) {} + function f4([{[foo]: x}]: [{ bar: number }]) {} + function f5([{[foo2()]: x}]: [{ bar: number }]) {} + + // report errors on type errors in computed properties used in destructuring + let [{[foo()]: bar6}] = [{bar: "bar"}]; + ~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}]; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'toExponential' does not exist on type 'string'. + + // destructuring assignment + ({[foo]: bar} = {bar: "bar"}); + + ({["bar"]: bar2} = {bar: "bar"}); + + ({[foo2()]: bar3} = {bar: "bar"}); + + [{[foo]: bar4}] = [{bar: "bar"}]; + [{[foo2()]: bar5}] = [{bar: "bar"}]; + + [{[foo()]: bar4}] = [{bar: "bar"}]; + ~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + [{[(1 + {})]: bar4}] = [{bar: "bar"}]; + ~~~~~~ +!!! error TS2365: Operator '+' cannot be applied to types 'number' and '{}'. + \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.js b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.js new file mode 100644 index 0000000000000..e6e19f93b802d --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring1_ES6.js @@ -0,0 +1,64 @@ +//// [computedPropertiesInDestructuring1_ES6.ts] +// destructuring in variable declarations +let foo = "bar"; +let {[foo]: bar} = {bar: "bar"}; + +let {["bar"]: bar2} = {bar: "bar"}; +let {[11]: bar2_1} = {11: "bar"}; + +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {bar: "bar"}; + +let [{[foo]: bar4}] = [{bar: "bar"}]; +let [{[foo2()]: bar5}] = [{bar: "bar"}]; + +function f1({["bar"]: x}: { bar: number }) {} +function f2({[foo]: x}: { bar: number }) {} +function f3({[foo2()]: x}: { bar: number }) {} +function f4([{[foo]: x}]: [{ bar: number }]) {} +function f5([{[foo2()]: x}]: [{ bar: number }]) {} + +// report errors on type errors in computed properties used in destructuring +let [{[foo()]: bar6}] = [{bar: "bar"}]; +let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}]; + +// destructuring assignment +({[foo]: bar} = {bar: "bar"}); + +({["bar"]: bar2} = {bar: "bar"}); + +({[foo2()]: bar3} = {bar: "bar"}); + +[{[foo]: bar4}] = [{bar: "bar"}]; +[{[foo2()]: bar5}] = [{bar: "bar"}]; + +[{[foo()]: bar4}] = [{bar: "bar"}]; +[{[(1 + {})]: bar4}] = [{bar: "bar"}]; + + +//// [computedPropertiesInDestructuring1_ES6.js] +// destructuring in variable declarations +let foo = "bar"; +let { [foo]: bar } = { bar: "bar" }; +let { ["bar"]: bar2 } = { bar: "bar" }; +let { [11]: bar2_1 } = { 11: "bar" }; +let foo2 = () => "bar"; +let { [foo2()]: bar3 } = { bar: "bar" }; +let [{ [foo]: bar4 }] = [{ bar: "bar" }]; +let [{ [foo2()]: bar5 }] = [{ bar: "bar" }]; +function f1({ ["bar"]: x }) { } +function f2({ [foo]: x }) { } +function f3({ [foo2()]: x }) { } +function f4([{ [foo]: x }]) { } +function f5([{ [foo2()]: x }]) { } +// report errors on type errors in computed properties used in destructuring +let [{ [foo()]: bar6 }] = [{ bar: "bar" }]; +let [{ [foo.toExponential()]: bar7 }] = [{ bar: "bar" }]; +// destructuring assignment +({ [foo]: bar } = { bar: "bar" }); +({ ["bar"]: bar2 } = { bar: "bar" }); +({ [foo2()]: bar3 } = { bar: "bar" }); +[{ [foo]: bar4 }] = [{ bar: "bar" }]; +[{ [foo2()]: bar5 }] = [{ bar: "bar" }]; +[{ [foo()]: bar4 }] = [{ bar: "bar" }]; +[{ [(1 + {})]: bar4 }] = [{ bar: "bar" }]; diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2.js b/tests/baselines/reference/computedPropertiesInDestructuring2.js new file mode 100644 index 0000000000000..8579881b77546 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring2.js @@ -0,0 +1,7 @@ +//// [computedPropertiesInDestructuring2.ts] +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {}; + +//// [computedPropertiesInDestructuring2.js] +var foo2 = function () { return "bar"; }; +var _a = foo2(), bar3 = {}[_a]; diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2.symbols b/tests/baselines/reference/computedPropertiesInDestructuring2.symbols new file mode 100644 index 0000000000000..4ae6d5323e187 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring2.symbols @@ -0,0 +1,8 @@ +=== tests/cases/compiler/computedPropertiesInDestructuring2.ts === +let foo2 = () => "bar"; +>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2.ts, 0, 3)) + +let {[foo2()]: bar3} = {}; +>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2.ts, 0, 3)) +>bar3 : Symbol(bar3, Decl(computedPropertiesInDestructuring2.ts, 1, 5)) + diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2.types b/tests/baselines/reference/computedPropertiesInDestructuring2.types new file mode 100644 index 0000000000000..0fa2066227047 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring2.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/computedPropertiesInDestructuring2.ts === +let foo2 = () => "bar"; +>foo2 : () => string +>() => "bar" : () => string +>"bar" : string + +let {[foo2()]: bar3} = {}; +>foo2() : string +>foo2 : () => string +>bar3 : any +>{} : {} + diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.js b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.js new file mode 100644 index 0000000000000..e0bd16287ee09 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.js @@ -0,0 +1,8 @@ +//// [computedPropertiesInDestructuring2_ES6.ts] + +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {}; + +//// [computedPropertiesInDestructuring2_ES6.js] +let foo2 = () => "bar"; +let { [foo2()]: bar3 } = {}; diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.symbols b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.symbols new file mode 100644 index 0000000000000..cd7cfda98441a --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts === + +let foo2 = () => "bar"; +>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2_ES6.ts, 1, 3)) + +let {[foo2()]: bar3} = {}; +>foo2 : Symbol(foo2, Decl(computedPropertiesInDestructuring2_ES6.ts, 1, 3)) +>bar3 : Symbol(bar3, Decl(computedPropertiesInDestructuring2_ES6.ts, 2, 5)) + diff --git a/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.types b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.types new file mode 100644 index 0000000000000..f0d8b1033c829 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesInDestructuring2_ES6.types @@ -0,0 +1,13 @@ +=== tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts === + +let foo2 = () => "bar"; +>foo2 : () => string +>() => "bar" : () => string +>"bar" : string + +let {[foo2()]: bar3} = {}; +>foo2() : string +>foo2 : () => string +>bar3 : any +>{} : {} + diff --git a/tests/baselines/reference/computedPropertyNames10_ES5.types b/tests/baselines/reference/computedPropertyNames10_ES5.types index 87648c1ed8015..9dea9cfca9390 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES5.types +++ b/tests/baselines/reference/computedPropertyNames10_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : {} ->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : {} +>v : { [0](): void; [""](): void; } +>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [0](): void; [""](): void; } [s]() { }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames10_ES6.types b/tests/baselines/reference/computedPropertyNames10_ES6.types index 996dfc99fe921..d2faa13898076 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES6.types +++ b/tests/baselines/reference/computedPropertyNames10_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : {} ->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : {} +>v : { [0](): void; [""](): void; } +>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [0](): void; [""](): void; } [s]() { }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.js b/tests/baselines/reference/computedPropertyNames11_ES5.js index 64c0b0bd67e35..0917f82477049 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES5.js +++ b/tests/baselines/reference/computedPropertyNames11_ES5.js @@ -46,16 +46,8 @@ var v = (_a = {}, enumerable: true, configurable: true }), - Object.defineProperty(_a, "", { - set: function (v) { }, - enumerable: true, - configurable: true - }), - Object.defineProperty(_a, 0, { - get: function () { return 0; }, - enumerable: true, - configurable: true - }), + , + , Object.defineProperty(_a, a, { set: function (v) { }, enumerable: true, diff --git a/tests/baselines/reference/computedPropertyNames11_ES5.types b/tests/baselines/reference/computedPropertyNames11_ES5.types index c3c59c2eb9c73..e0787fc3ee712 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES5.types +++ b/tests/baselines/reference/computedPropertyNames11_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : {} ->{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : {} +>v : { [0]: number; [""]: any; } +>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [0]: number; [""]: any; } get [s]() { return 0; }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames11_ES6.types b/tests/baselines/reference/computedPropertyNames11_ES6.types index ef11511baaed7..8ad31a7c2a14e 100644 --- a/tests/baselines/reference/computedPropertyNames11_ES6.types +++ b/tests/baselines/reference/computedPropertyNames11_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : {} ->{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : {} +>v : { [0]: number; [""]: any; } +>{ get [s]() { return 0; }, set [n](v) { }, get [s + s]() { return 0; }, set [s + n](v) { }, get [+s]() { return 0; }, set [""](v) { }, get [0]() { return 0; }, set [a](v) { }, get [true]() { return 0; }, set [`hello bye`](v) { }, get [`hello ${a} bye`]() { return 0; }} : { [0]: number; [""]: any; } get [s]() { return 0; }, >s : string diff --git a/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt index 9d07f34f3c4eb..71f81c27245f9 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames12_ES5.errors.txt @@ -3,15 +3,13 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(6, tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(7,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(9,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. -tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(10,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. -tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(11,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(12,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(13,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(14,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(15,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts (11 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts (9 errors) ==== var s: string; var n: number; var a: any; @@ -32,11 +30,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES5.ts(15 ~~~~ !!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. static [""]: number; - ~~~~ -!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. [0]: number; - ~~~ -!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. [a]: number; ~~~ !!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. diff --git a/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt index f0a2267f8b365..8d8cce7e1408d 100644 --- a/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames12_ES6.errors.txt @@ -3,15 +3,13 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(6, tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(7,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(9,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. -tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(10,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. -tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(11,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(12,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(13,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(14,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(15,12): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts (11 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts (9 errors) ==== var s: string; var n: number; var a: any; @@ -32,11 +30,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames12_ES6.ts(15 ~~~~ !!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. static [""]: number; - ~~~~ -!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. [0]: number; - ~~~ -!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. [a]: number; ~~~ !!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. diff --git a/tests/baselines/reference/computedPropertyNames16_ES5.js b/tests/baselines/reference/computedPropertyNames16_ES5.js index 2c7316e13982c..f4d90579d63aa 100644 --- a/tests/baselines/reference/computedPropertyNames16_ES5.js +++ b/tests/baselines/reference/computedPropertyNames16_ES5.js @@ -48,16 +48,6 @@ var C = (function () { enumerable: true, configurable: true }); - Object.defineProperty(C, "", { - set: function (v) { }, - enumerable: true, - configurable: true - }); - Object.defineProperty(C.prototype, 0, { - get: function () { return 0; }, - enumerable: true, - configurable: true - }); Object.defineProperty(C.prototype, a, { set: function (v) { }, enumerable: true, diff --git a/tests/baselines/reference/computedPropertyNames36_ES5.js b/tests/baselines/reference/computedPropertyNames36_ES5.js index 5519a6d284caf..4bb10ea754395 100644 --- a/tests/baselines/reference/computedPropertyNames36_ES5.js +++ b/tests/baselines/reference/computedPropertyNames36_ES5.js @@ -27,10 +27,6 @@ var C = (function () { Object.defineProperty(C.prototype, "get1", { // Computed properties get: function () { return new Foo; }, - enumerable: true, - configurable: true - }); - Object.defineProperty(C.prototype, "set1", { set: function (p) { }, enumerable: true, configurable: true diff --git a/tests/baselines/reference/computedPropertyNames37_ES5.js b/tests/baselines/reference/computedPropertyNames37_ES5.js index 54a7243f3fae8..c2a346608fe79 100644 --- a/tests/baselines/reference/computedPropertyNames37_ES5.js +++ b/tests/baselines/reference/computedPropertyNames37_ES5.js @@ -27,10 +27,6 @@ var C = (function () { Object.defineProperty(C.prototype, "get1", { // Computed properties get: function () { return new Foo; }, - enumerable: true, - configurable: true - }); - Object.defineProperty(C.prototype, "set1", { set: function (p) { }, enumerable: true, configurable: true diff --git a/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt index e8ceef0d58115..482978064d167 100644 --- a/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt @@ -1,7 +1,9 @@ +tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(8,5): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(8,5): error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(9,5): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts (1 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts (3 errors) ==== class Foo { x } class Foo2 { x; y } @@ -10,7 +12,11 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(8, // Computed properties [""]() { return new Foo } + ~~~~ +!!! error TS2393: Duplicate function implementation. ~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'. [""]() { return new Foo2 } + ~~~~ +!!! error TS2393: Duplicate function implementation. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt index 1a032a87b2b00..669d0d04e6612 100644 --- a/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt @@ -1,7 +1,9 @@ +tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(8,5): error TS2393: Duplicate function implementation. tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(8,5): error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(9,5): error TS2393: Duplicate function implementation. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts (1 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts (3 errors) ==== class Foo { x } class Foo2 { x; y } @@ -10,7 +12,11 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(8, // Computed properties [""]() { return new Foo } + ~~~~ +!!! error TS2393: Duplicate function implementation. ~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'. [""]() { return new Foo2 } + ~~~~ +!!! error TS2393: Duplicate function implementation. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt index 94153c47aa5d4..bdb978220a03d 100644 --- a/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8,5): error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts (2 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts (1 errors) ==== class Foo { x } class Foo2 { x; y } @@ -11,8 +10,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8, // Computed properties [""]: Foo; - ~~~~ -!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. ~~~~~~~~~~ !!! error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt index 1f4e27d6e810a..9feb6ba3d32ae 100644 --- a/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8,5): error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8,5): error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts (2 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts (1 errors) ==== class Foo { x } class Foo2 { x; y } @@ -11,8 +10,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8, // Computed properties [""]: Foo; - ~~~~ -!!! error TS1166: A computed property name in a class property declaration must directly refer to a built-in symbol. ~~~~~~~~~~ !!! error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames43_ES5.js b/tests/baselines/reference/computedPropertyNames43_ES5.js index c3b7f6a71d0e9..57026c3c70694 100644 --- a/tests/baselines/reference/computedPropertyNames43_ES5.js +++ b/tests/baselines/reference/computedPropertyNames43_ES5.js @@ -41,10 +41,6 @@ var D = (function (_super) { Object.defineProperty(D.prototype, "get1", { // Computed properties get: function () { return new Foo; }, - enumerable: true, - configurable: true - }); - Object.defineProperty(D.prototype, "set1", { set: function (p) { }, enumerable: true, configurable: true diff --git a/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt index 83855c5f0b7e2..8baae68f33799 100644 --- a/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt @@ -1,12 +1,15 @@ +tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(5,5): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(11,5): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts (1 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts (2 errors) ==== class Foo { x } class Foo2 { x; y } class C { get ["get1"]() { return new Foo } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. } class D extends C { diff --git a/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt index 963e01ed86bd8..e329785f4cf53 100644 --- a/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt @@ -1,12 +1,15 @@ +tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(5,5): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(11,5): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. -==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts (1 errors) ==== +==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts (2 errors) ==== class Foo { x } class Foo2 { x; y } class C { get ["get1"]() { return new Foo } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. } class D extends C { diff --git a/tests/baselines/reference/computedPropertyNames4_ES5.types b/tests/baselines/reference/computedPropertyNames4_ES5.types index 51baca2658629..6984d2e69b8a4 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES5.types +++ b/tests/baselines/reference/computedPropertyNames4_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : {} ->{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : {} +>v : { [0]: number; [""]: number; } +>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [0]: number; [""]: number; } [s]: 0, >s : string diff --git a/tests/baselines/reference/computedPropertyNames4_ES6.types b/tests/baselines/reference/computedPropertyNames4_ES6.types index 0526704951726..1fece561f5ae8 100644 --- a/tests/baselines/reference/computedPropertyNames4_ES6.types +++ b/tests/baselines/reference/computedPropertyNames4_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : {} ->{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : {} +>v : { [0]: number; [""]: number; } +>{ [s]: 0, [n]: n, [s + s]: 1, [s + n]: 2, [+s]: s, [""]: 0, [0]: 0, [a]: 1, [true]: 0, [`hello bye`]: 0, [`hello ${a} bye`]: 0} : { [0]: number; [""]: number; } [s]: 0, >s : string diff --git a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types index 9470aee8eb6f0..147b296650998 100644 --- a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types +++ b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES5.types @@ -1,7 +1,7 @@ === tests/cases/conformance/es6/computedProperties/computedPropertyNamesSourceMap2_ES5.ts === var v = { ->v : {} ->{ ["hello"]() { debugger; }} : {} +>v : { ["hello"](): void; } +>{ ["hello"]() { debugger; }} : { ["hello"](): void; } ["hello"]() { >"hello" : string diff --git a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types index c4f02155a95e9..0033468036299 100644 --- a/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types +++ b/tests/baselines/reference/computedPropertyNamesSourceMap2_ES6.types @@ -1,7 +1,7 @@ === tests/cases/conformance/es6/computedProperties/computedPropertyNamesSourceMap2_ES6.ts === var v = { ->v : {} ->{ ["hello"]() { debugger; }} : {} +>v : { ["hello"](): void; } +>{ ["hello"]() { debugger; }} : { ["hello"](): void; } ["hello"]() { >"hello" : string diff --git a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js index ece24d691da30..e7f88b92775a4 100644 --- a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js +++ b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.js @@ -10,16 +10,16 @@ class C { static get ["computedname"]() { return ""; } - get ["computedname"]() { + get ["computedname1"]() { return ""; } - get ["computedname"]() { + get ["computedname2"]() { return ""; } - set ["computedname"](x: any) { + set ["computedname3"](x: any) { } - set ["computedname"](y: string) { + set ["computedname4"](y: string) { } set foo(a: string) { } @@ -38,15 +38,15 @@ class C { static get ["computedname"]() { return ""; } - get ["computedname"]() { + get ["computedname1"]() { return ""; } - get ["computedname"]() { + get ["computedname2"]() { return ""; } - set ["computedname"](x) { + set ["computedname3"](x) { } - set ["computedname"](y) { + set ["computedname4"](y) { } set foo(a) { } static set bar(b) { } diff --git a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols index 2d249348f9bad..b2b1a000dc968 100644 --- a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols +++ b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.symbols @@ -21,18 +21,18 @@ class C { static get ["computedname"]() { return ""; } - get ["computedname"]() { + get ["computedname1"]() { return ""; } - get ["computedname"]() { + get ["computedname2"]() { return ""; } - set ["computedname"](x: any) { ->x : Symbol(x, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 18, 25)) + set ["computedname3"](x: any) { +>x : Symbol(x, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 18, 26)) } - set ["computedname"](y: string) { ->y : Symbol(y, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 20, 25)) + set ["computedname4"](y: string) { +>y : Symbol(y, Decl(emitClassDeclarationWithGetterSetterInES6.ts, 20, 26)) } set foo(a: string) { } diff --git a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types index 292fb961b10c4..e4f7d6c00b47b 100644 --- a/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types +++ b/tests/baselines/reference/emitClassDeclarationWithGetterSetterInES6.types @@ -25,25 +25,25 @@ class C { return ""; >"" : string } - get ["computedname"]() { ->"computedname" : string + get ["computedname1"]() { +>"computedname1" : string return ""; >"" : string } - get ["computedname"]() { ->"computedname" : string + get ["computedname2"]() { +>"computedname2" : string return ""; >"" : string } - set ["computedname"](x: any) { ->"computedname" : string + set ["computedname3"](x: any) { +>"computedname3" : string >x : any } - set ["computedname"](y: string) { ->"computedname" : string + set ["computedname4"](y: string) { +>"computedname4" : string >y : string } diff --git a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js index fc0a510461bb1..8a79d45b6786c 100644 --- a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js +++ b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.js @@ -2,18 +2,18 @@ class D { _bar: string; foo() { } - ["computedName"]() { } - ["computedName"](a: string) { } - ["computedName"](a: string): number { return 1; } + ["computedName1"]() { } + ["computedName2"](a: string) { } + ["computedName3"](a: string): number { return 1; } bar(): string { return this._bar; } baz(a: any, x: string): string { return "HELLO"; } - static ["computedname"]() { } - static ["computedname"](a: string) { } - static ["computedname"](a: string): boolean { return true; } + static ["computedname4"]() { } + static ["computedname5"](a: string) { } + static ["computedname6"](a: string): boolean { return true; } static staticMethod() { var x = 1 + 2; return x @@ -25,18 +25,18 @@ class D { //// [emitClassDeclarationWithMethodInES6.js] class D { foo() { } - ["computedName"]() { } - ["computedName"](a) { } - ["computedName"](a) { return 1; } + ["computedName1"]() { } + ["computedName2"](a) { } + ["computedName3"](a) { return 1; } bar() { return this._bar; } baz(a, x) { return "HELLO"; } - static ["computedname"]() { } - static ["computedname"](a) { } - static ["computedname"](a) { return true; } + static ["computedname4"]() { } + static ["computedname5"](a) { } + static ["computedname6"](a) { return true; } static staticMethod() { var x = 1 + 2; return x; diff --git a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols index b7a4dbbf341a1..970076f6b7837 100644 --- a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols +++ b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.symbols @@ -8,15 +8,15 @@ class D { foo() { } >foo : Symbol(foo, Decl(emitClassDeclarationWithMethodInES6.ts, 1, 17)) - ["computedName"]() { } - ["computedName"](a: string) { } ->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 4, 21)) + ["computedName1"]() { } + ["computedName2"](a: string) { } +>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 4, 22)) - ["computedName"](a: string): number { return 1; } ->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 21)) + ["computedName3"](a: string): number { return 1; } +>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 22)) bar(): string { ->bar : Symbol(bar, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 53)) +>bar : Symbol(bar, Decl(emitClassDeclarationWithMethodInES6.ts, 5, 54)) return this._bar; >this._bar : Symbol(_bar, Decl(emitClassDeclarationWithMethodInES6.ts, 0, 9)) @@ -30,15 +30,15 @@ class D { return "HELLO"; } - static ["computedname"]() { } - static ["computedname"](a: string) { } ->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 13, 28)) + static ["computedname4"]() { } + static ["computedname5"](a: string) { } +>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 13, 29)) - static ["computedname"](a: string): boolean { return true; } ->a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 28)) + static ["computedname6"](a: string): boolean { return true; } +>a : Symbol(a, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 29)) static staticMethod() { ->staticMethod : Symbol(D.staticMethod, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 64)) +>staticMethod : Symbol(D.staticMethod, Decl(emitClassDeclarationWithMethodInES6.ts, 14, 65)) var x = 1 + 2; >x : Symbol(x, Decl(emitClassDeclarationWithMethodInES6.ts, 16, 11)) diff --git a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types index 10ae930c24486..02a90729486a7 100644 --- a/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types +++ b/tests/baselines/reference/emitClassDeclarationWithMethodInES6.types @@ -8,15 +8,15 @@ class D { foo() { } >foo : () => void - ["computedName"]() { } ->"computedName" : string + ["computedName1"]() { } +>"computedName1" : string - ["computedName"](a: string) { } ->"computedName" : string + ["computedName2"](a: string) { } +>"computedName2" : string >a : string - ["computedName"](a: string): number { return 1; } ->"computedName" : string + ["computedName3"](a: string): number { return 1; } +>"computedName3" : string >a : string >1 : number @@ -36,15 +36,15 @@ class D { return "HELLO"; >"HELLO" : string } - static ["computedname"]() { } ->"computedname" : string + static ["computedname4"]() { } +>"computedname4" : string - static ["computedname"](a: string) { } ->"computedname" : string + static ["computedname5"](a: string) { } +>"computedname5" : string >a : string - static ["computedname"](a: string): boolean { return true; } ->"computedname" : string + static ["computedname6"](a: string): boolean { return true; } +>"computedname6" : string >a : string >true : boolean diff --git a/tests/baselines/reference/literalsInComputedProperties1.errors.txt b/tests/baselines/reference/literalsInComputedProperties1.errors.txt new file mode 100644 index 0000000000000..e9972229f795f --- /dev/null +++ b/tests/baselines/reference/literalsInComputedProperties1.errors.txt @@ -0,0 +1,66 @@ +tests/cases/compiler/literalsInComputedProperties1.ts(40,5): error TS2452: An enum member cannot have a numeric name. +tests/cases/compiler/literalsInComputedProperties1.ts(41,5): error TS2452: An enum member cannot have a numeric name. +tests/cases/compiler/literalsInComputedProperties1.ts(42,5): error TS2452: An enum member cannot have a numeric name. +tests/cases/compiler/literalsInComputedProperties1.ts(43,5): error TS2452: An enum member cannot have a numeric name. + + +==== tests/cases/compiler/literalsInComputedProperties1.ts (4 errors) ==== + + let x = { + 1:1, + [2]:1, + "3":1, + ["4"]:1 + } + x[1].toExponential(); + x[2].toExponential(); + x[3].toExponential(); + x[4].toExponential(); + + interface A { + 1:number; + [2]:number; + "3":number; + ["4"]:number; + } + + let y:A; + y[1].toExponential(); + y[2].toExponential(); + y[3].toExponential(); + y[4].toExponential(); + + class C { + 1:number; + [2]:number; + "3":number; + ["4"]:number; + } + + let z:C; + z[1].toExponential(); + z[2].toExponential(); + z[3].toExponential(); + z[4].toExponential(); + + enum X { + 1 = 1, + ~ +!!! error TS2452: An enum member cannot have a numeric name. + [2] = 2, + ~~~ +!!! error TS2452: An enum member cannot have a numeric name. + "3" = 3, + ~~~ +!!! error TS2452: An enum member cannot have a numeric name. + ["4"] = 4, + ~~~~~ +!!! error TS2452: An enum member cannot have a numeric name. + "foo" = 5, + ["bar"] = 6 + } + + let a = X["foo"]; + let a0 = X["bar"]; + + // TODO: make sure that enum still disallow template literals as member names \ No newline at end of file diff --git a/tests/baselines/reference/literalsInComputedProperties1.js b/tests/baselines/reference/literalsInComputedProperties1.js new file mode 100644 index 0000000000000..ef11dbff6ea4a --- /dev/null +++ b/tests/baselines/reference/literalsInComputedProperties1.js @@ -0,0 +1,94 @@ +//// [literalsInComputedProperties1.ts] + +let x = { + 1:1, + [2]:1, + "3":1, + ["4"]:1 +} +x[1].toExponential(); +x[2].toExponential(); +x[3].toExponential(); +x[4].toExponential(); + +interface A { + 1:number; + [2]:number; + "3":number; + ["4"]:number; +} + +let y:A; +y[1].toExponential(); +y[2].toExponential(); +y[3].toExponential(); +y[4].toExponential(); + +class C { + 1:number; + [2]:number; + "3":number; + ["4"]:number; +} + +let z:C; +z[1].toExponential(); +z[2].toExponential(); +z[3].toExponential(); +z[4].toExponential(); + +enum X { + 1 = 1, + [2] = 2, + "3" = 3, + ["4"] = 4, + "foo" = 5, + ["bar"] = 6 +} + +let a = X["foo"]; +let a0 = X["bar"]; + +// TODO: make sure that enum still disallow template literals as member names + +//// [literalsInComputedProperties1.js] +var x = (_a = { + 1: 1 + }, + _a[2] = 1, + _a["3"] = 1, + _a["4"] = 1, + _a +); +x[1].toExponential(); +x[2].toExponential(); +x[3].toExponential(); +x[4].toExponential(); +var y; +y[1].toExponential(); +y[2].toExponential(); +y[3].toExponential(); +y[4].toExponential(); +var C = (function () { + function C() { + } + return C; +})(); +var z; +z[1].toExponential(); +z[2].toExponential(); +z[3].toExponential(); +z[4].toExponential(); +var X; +(function (X) { + X[X["1"] = 1] = "1"; + X[X[2] = 2] = 2; + X[X["3"] = 3] = "3"; + X[X["4"] = 4] = "4"; + X[X["foo"] = 5] = "foo"; + X[X["bar"] = 6] = "bar"; +})(X || (X = {})); +var a = X["foo"]; +var a0 = X["bar"]; +var _a; +// TODO: make sure that enum still disallow template literals as member names diff --git a/tests/cases/compiler/computedPropertiesInDestructuring1.ts b/tests/cases/compiler/computedPropertiesInDestructuring1.ts new file mode 100644 index 0000000000000..d3ccaa57ad105 --- /dev/null +++ b/tests/cases/compiler/computedPropertiesInDestructuring1.ts @@ -0,0 +1,36 @@ +// destructuring in variable declarations +let foo = "bar"; +let {[foo]: bar} = {bar: "bar"}; + +let {["bar"]: bar2} = {bar: "bar"}; + +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {bar: "bar"}; + +let [{[foo]: bar4}] = [{bar: "bar"}]; +let [{[foo2()]: bar5}] = [{bar: "bar"}]; + +function f1({["bar"]: x}: { bar: number }) {} +function f2({[foo]: x}: { bar: number }) {} +function f3({[foo2()]: x}: { bar: number }) {} +function f4([{[foo]: x}]: [{ bar: number }]) {} +function f5([{[foo2()]: x}]: [{ bar: number }]) {} + +// report errors on type errors in computed properties used in destructuring +let [{[foo()]: bar6}] = [{bar: "bar"}]; +let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}]; + +// destructuring assignment +({[foo]: bar} = {bar: "bar"}); + +({["bar"]: bar2} = {bar: "bar"}); + +({[foo2()]: bar3} = {bar: "bar"}); + +[{[foo]: bar4}] = [{bar: "bar"}]; +[{[foo2()]: bar5}] = [{bar: "bar"}]; + +[{[foo()]: bar4}] = [{bar: "bar"}]; +[{[(1 + {})]: bar4}] = [{bar: "bar"}]; + + diff --git a/tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts b/tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts new file mode 100644 index 0000000000000..4951e474fdba7 --- /dev/null +++ b/tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts @@ -0,0 +1,36 @@ +// @target: ES6 +// destructuring in variable declarations +let foo = "bar"; +let {[foo]: bar} = {bar: "bar"}; + +let {["bar"]: bar2} = {bar: "bar"}; +let {[11]: bar2_1} = {11: "bar"}; + +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {bar: "bar"}; + +let [{[foo]: bar4}] = [{bar: "bar"}]; +let [{[foo2()]: bar5}] = [{bar: "bar"}]; + +function f1({["bar"]: x}: { bar: number }) {} +function f2({[foo]: x}: { bar: number }) {} +function f3({[foo2()]: x}: { bar: number }) {} +function f4([{[foo]: x}]: [{ bar: number }]) {} +function f5([{[foo2()]: x}]: [{ bar: number }]) {} + +// report errors on type errors in computed properties used in destructuring +let [{[foo()]: bar6}] = [{bar: "bar"}]; +let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}]; + +// destructuring assignment +({[foo]: bar} = {bar: "bar"}); + +({["bar"]: bar2} = {bar: "bar"}); + +({[foo2()]: bar3} = {bar: "bar"}); + +[{[foo]: bar4}] = [{bar: "bar"}]; +[{[foo2()]: bar5}] = [{bar: "bar"}]; + +[{[foo()]: bar4}] = [{bar: "bar"}]; +[{[(1 + {})]: bar4}] = [{bar: "bar"}]; diff --git a/tests/cases/compiler/computedPropertiesInDestructuring2.ts b/tests/cases/compiler/computedPropertiesInDestructuring2.ts new file mode 100644 index 0000000000000..806c528c17cc6 --- /dev/null +++ b/tests/cases/compiler/computedPropertiesInDestructuring2.ts @@ -0,0 +1,2 @@ +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {}; \ No newline at end of file diff --git a/tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts b/tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts new file mode 100644 index 0000000000000..c21f86bed1cee --- /dev/null +++ b/tests/cases/compiler/computedPropertiesInDestructuring2_ES6.ts @@ -0,0 +1,4 @@ +// @target: ES6 + +let foo2 = () => "bar"; +let {[foo2()]: bar3} = {}; \ No newline at end of file diff --git a/tests/cases/compiler/literalsInComputedProperties1.ts b/tests/cases/compiler/literalsInComputedProperties1.ts new file mode 100644 index 0000000000000..e3fed5b80aab1 --- /dev/null +++ b/tests/cases/compiler/literalsInComputedProperties1.ts @@ -0,0 +1,52 @@ +// @noImplicitAny: true + +let x = { + 1:1, + [2]:1, + "3":1, + ["4"]:1 +} +x[1].toExponential(); +x[2].toExponential(); +x[3].toExponential(); +x[4].toExponential(); + +interface A { + 1:number; + [2]:number; + "3":number; + ["4"]:number; +} + +let y:A; +y[1].toExponential(); +y[2].toExponential(); +y[3].toExponential(); +y[4].toExponential(); + +class C { + 1:number; + [2]:number; + "3":number; + ["4"]:number; +} + +let z:C; +z[1].toExponential(); +z[2].toExponential(); +z[3].toExponential(); +z[4].toExponential(); + +enum X { + 1 = 1, + [2] = 2, + "3" = 3, + ["4"] = 4, + "foo" = 5, + ["bar"] = 6 +} + +let a = X["foo"]; +let a0 = X["bar"]; + +// TODO: make sure that enum still disallow template literals as member names \ No newline at end of file diff --git a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts index 70c0b35763e9b..54c95c95a37d5 100644 --- a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts +++ b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithGetterSetterInES6.ts @@ -10,16 +10,16 @@ class C { static get ["computedname"]() { return ""; } - get ["computedname"]() { + get ["computedname1"]() { return ""; } - get ["computedname"]() { + get ["computedname2"]() { return ""; } - set ["computedname"](x: any) { + set ["computedname3"](x: any) { } - set ["computedname"](y: string) { + set ["computedname4"](y: string) { } set foo(a: string) { } diff --git a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts index c5d95bc6cb16f..b7399a3511c96 100644 --- a/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts +++ b/tests/cases/conformance/es6/classDeclaration/emitClassDeclarationWithMethodInES6.ts @@ -2,18 +2,18 @@ class D { _bar: string; foo() { } - ["computedName"]() { } - ["computedName"](a: string) { } - ["computedName"](a: string): number { return 1; } + ["computedName1"]() { } + ["computedName2"](a: string) { } + ["computedName3"](a: string): number { return 1; } bar(): string { return this._bar; } baz(a: any, x: string): string { return "HELLO"; } - static ["computedname"]() { } - static ["computedname"](a: string) { } - static ["computedname"](a: string): boolean { return true; } + static ["computedname4"]() { } + static ["computedname5"](a: string) { } + static ["computedname6"](a: string): boolean { return true; } static staticMethod() { var x = 1 + 2; return x