@@ -5280,17 +5280,18 @@ namespace ts {
5280
5280
let objectFlags = ObjectFlags.ObjectLiteral;
5281
5281
forEach(pattern.elements, e => {
5282
5282
const name = e.propertyName || <Identifier>e.name;
5283
- if (isComputedNonLiteralName(name)) {
5284
- // do not include computed properties in the implied type
5285
- objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties;
5286
- return;
5287
- }
5288
5283
if (e.dotDotDotToken) {
5289
5284
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
5290
5285
return;
5291
5286
}
5292
5287
5293
- const text = getTextOfPropertyName(name);
5288
+ const exprType = getLiteralTypeFromPropertyName(name);
5289
+ if (!isTypeUsableAsPropertyName(exprType)) {
5290
+ // do not include computed properties in the implied type
5291
+ objectFlags |= ObjectFlags.ObjectLiteralPatternWithComputedProperties;
5292
+ return;
5293
+ }
5294
+ const text = getPropertyNameFromType(exprType);
5294
5295
const flags = SymbolFlags.Property | (e.initializer ? SymbolFlags.Optional : 0);
5295
5296
const symbol = createSymbol(flags, text);
5296
5297
symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
@@ -6399,9 +6400,9 @@ namespace ts {
6399
6400
}
6400
6401
6401
6402
/**
6402
- * Indicates whether a type can be used as a late-bound name.
6403
+ * Indicates whether a type can be used as a property name.
6403
6404
*/
6404
- function isTypeUsableAsLateBoundName (type: Type): type is LiteralType | UniqueESSymbolType {
6405
+ function isTypeUsableAsPropertyName (type: Type): type is StringLiteralType | NumberLiteralType | UniqueESSymbolType {
6405
6406
return !!(type.flags & TypeFlags.StringOrNumberLiteralOrUnique);
6406
6407
}
6407
6408
@@ -6416,7 +6417,7 @@ namespace ts {
6416
6417
function isLateBindableName(node: DeclarationName): node is LateBoundName {
6417
6418
return isComputedPropertyName(node)
6418
6419
&& isEntityNameExpression(node.expression)
6419
- && isTypeUsableAsLateBoundName (checkComputedPropertyName(node));
6420
+ && isTypeUsableAsPropertyName (checkComputedPropertyName(node));
6420
6421
}
6421
6422
6422
6423
function isLateBoundName(name: __String): boolean {
@@ -6448,21 +6449,14 @@ namespace ts {
6448
6449
}
6449
6450
6450
6451
/**
6451
- * Gets the late-bound name for a computed property name .
6452
+ * Gets the symbolic name for a member from its type .
6452
6453
*/
6453
- function getLateBoundName(node: LateBoundName) {
6454
- return getLateBoundNameFromType(checkComputedPropertyName(node));
6455
- }
6456
-
6457
- /**
6458
- * Gets the symbolic name for a late-bound member from its type.
6459
- */
6460
- function getLateBoundNameFromType(type: LiteralType | UniqueESSymbolType): __String {
6454
+ function getPropertyNameFromType(type: StringLiteralType | NumberLiteralType | UniqueESSymbolType): __String {
6461
6455
if (type.flags & TypeFlags.UniqueESSymbol) {
6462
- return `__@${type.symbol.escapedName}@${getSymbolId( type.symbol)}` as __String ;
6456
+ return (<UniqueESSymbolType> type).escapedName ;
6463
6457
}
6464
6458
if (type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
6465
- return escapeLeadingUnderscores("" + (<LiteralType >type).value);
6459
+ return escapeLeadingUnderscores("" + (<StringLiteralType | NumberLiteralType >type).value);
6466
6460
}
6467
6461
return Debug.fail();
6468
6462
}
@@ -6525,8 +6519,8 @@ namespace ts {
6525
6519
// fall back to the early-bound name of this member.
6526
6520
links.resolvedSymbol = decl.symbol;
6527
6521
const type = checkComputedPropertyName(decl.name);
6528
- if (isTypeUsableAsLateBoundName (type)) {
6529
- const memberName = getLateBoundNameFromType (type);
6522
+ if (isTypeUsableAsPropertyName (type)) {
6523
+ const memberName = getPropertyNameFromType (type);
6530
6524
const symbolFlags = decl.symbol.flags;
6531
6525
6532
6526
// Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations.
@@ -7175,8 +7169,8 @@ namespace ts {
7175
7169
const propType = instantiateType(templateType, templateMapper);
7176
7170
// If the current iteration type constituent is a string literal type, create a property.
7177
7171
// Otherwise, for type string create a string index signature.
7178
- if (t.flags & TypeFlags.StringOrNumberLiteralOrUnique ) {
7179
- const propName = getLateBoundNameFromType(t as LiteralType );
7172
+ if (isTypeUsableAsPropertyName(t) ) {
7173
+ const propName = getPropertyNameFromType(t );
7180
7174
const modifiersProp = getPropertyOfType(modifiersType, propName);
7181
7175
const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional ||
7182
7176
!(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional);
@@ -7361,7 +7355,8 @@ namespace ts {
7361
7355
function isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes): boolean {
7362
7356
const list = obj.properties as NodeArray<ObjectLiteralElementLike | JsxAttributeLike>;
7363
7357
return list.some(property => {
7364
- const name = property.name && !isComputedNonLiteralName(property.name) ? getTextOfPropertyName(property.name) : undefined;
7358
+ const nameType = property.name && getLiteralTypeFromPropertyName(property.name);
7359
+ const name = nameType && isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
7365
7360
const expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
7366
7361
return !!expected && isLiteralType(expected) && !isTypeIdenticalTo(getTypeOfNode(property), expected);
7367
7362
});
@@ -9724,8 +9719,8 @@ namespace ts {
9724
9719
9725
9720
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean, missingType: Type) {
9726
9721
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
9727
- const propName = isTypeUsableAsLateBoundName (indexType) ?
9728
- getLateBoundNameFromType (indexType) :
9722
+ const propName = isTypeUsableAsPropertyName (indexType) ?
9723
+ getPropertyNameFromType (indexType) :
9729
9724
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
9730
9725
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
9731
9726
accessNode && isPropertyName(accessNode) ?
@@ -10415,6 +10410,7 @@ namespace ts {
10415
10410
function createUniqueESSymbolType(symbol: Symbol) {
10416
10411
const type = <UniqueESSymbolType>createType(TypeFlags.UniqueESSymbol);
10417
10412
type.symbol = symbol;
10413
+ type.escapedName = `__@${type.symbol.escapedName}@${getSymbolId(type.symbol)}` as __String;
10418
10414
return type;
10419
10415
}
10420
10416
@@ -11302,7 +11298,7 @@ namespace ts {
11302
11298
}
11303
11299
if (resultObj.error) {
11304
11300
const reportedDiag = resultObj.error;
11305
- const propertyName = isTypeUsableAsLateBoundName (nameType) ? getLateBoundNameFromType (nameType) : undefined;
11301
+ const propertyName = isTypeUsableAsPropertyName (nameType) ? getPropertyNameFromType (nameType) : undefined;
11306
11302
const targetProp = propertyName !== undefined ? getPropertyOfType(target, propertyName) : undefined;
11307
11303
11308
11304
let issuedElaboration = false;
@@ -15066,10 +15062,9 @@ namespace ts {
15066
15062
}
15067
15063
15068
15064
function getTypeOfDestructuredProperty(type: Type, name: PropertyName) {
15069
- const text = !isComputedNonLiteralName(name) ? getTextOfPropertyName(name) :
15070
- isLateBindableName(name) ? getLateBoundName(name) :
15071
- undefined;
15072
- if (text === undefined) return errorType;
15065
+ const nameType = getLiteralTypeFromPropertyName(name);
15066
+ if (!isTypeUsableAsPropertyName(nameType)) return errorType;
15067
+ const text = getPropertyNameFromType(nameType);
15073
15068
return getConstraintForLocation(getTypeOfPropertyOfType(type, text), name) ||
15074
15069
isNumericLiteralName(text) && getIndexTypeOfType(type, IndexKind.Number) ||
15075
15070
getIndexTypeOfType(type, IndexKind.String) ||
@@ -17202,8 +17197,11 @@ namespace ts {
17202
17197
const name = declaration.propertyName || declaration.name;
17203
17198
const parentType = getContextualTypeForVariableLikeDeclaration(parentDeclaration);
17204
17199
if (parentType && !isBindingPattern(name) && !isComputedNonLiteralName(name)) {
17205
- const text = getTextOfPropertyName(name);
17206
- return getTypeOfPropertyOfType(parentType, text);
17200
+ const nameType = getLiteralTypeFromPropertyName(name);
17201
+ if (isTypeUsableAsPropertyName(nameType)) {
17202
+ const text = getPropertyNameFromType(nameType);
17203
+ return getTypeOfPropertyOfType(parentType, text);
17204
+ }
17207
17205
}
17208
17206
}
17209
17207
@@ -18146,10 +18144,9 @@ namespace ts {
18146
18144
}
18147
18145
}
18148
18146
typeFlags |= type.flags;
18149
- const nameType = computedNameType && computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique ?
18150
- <LiteralType | UniqueESSymbolType>computedNameType : undefined;
18147
+ const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
18151
18148
const prop = nameType ?
18152
- createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType (nameType), CheckFlags.Late) :
18149
+ createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType (nameType), CheckFlags.Late) :
18153
18150
createSymbol(SymbolFlags.Property | member.flags, member.escapedName);
18154
18151
if (nameType) {
18155
18152
prop.nameType = nameType;
@@ -22209,15 +22206,15 @@ namespace ts {
22209
22206
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: NodeArray<ObjectLiteralElementLike>, rightIsThis = false) {
22210
22207
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
22211
22208
const name = property.name;
22212
- if (!isComputedNonLiteralName(name)) {
22213
- const text = getTextOfPropertyName(name);
22209
+ const exprType = getLiteralTypeFromPropertyName(name);
22210
+ if (isTypeUsableAsPropertyName(exprType)) {
22211
+ const text = getPropertyNameFromType(exprType);
22214
22212
const prop = getPropertyOfType(objectLiteralType, text);
22215
22213
if (prop) {
22216
22214
markPropertyAsReferenced(prop, property, rightIsThis);
22217
22215
checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop);
22218
22216
}
22219
22217
}
22220
- const exprType = getLiteralTypeFromPropertyName(name);
22221
22218
const elementType = getIndexedAccessType(objectLiteralType, exprType, name);
22222
22219
const type = getFlowTypeOfDestructuring(property, elementType);
22223
22220
return checkDestructuringAssignment(property.kind === SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type);
@@ -25532,12 +25529,15 @@ namespace ts {
25532
25529
const parent = node.parent.parent;
25533
25530
const parentType = getTypeForBindingElementParent(parent);
25534
25531
const name = node.propertyName || node.name;
25535
- if (!isBindingPattern(name) && !isComputedNonLiteralName(name)) {
25536
- const nameText = getTextOfPropertyName(name);
25537
- const property = getPropertyOfType(parentType!, nameText); // TODO: GH#18217
25538
- if (property) {
25539
- markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
25540
- checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, parentType!, property);
25532
+ if (!isBindingPattern(name) && parentType) {
25533
+ const exprType = getLiteralTypeFromPropertyName(name);
25534
+ if (isTypeUsableAsPropertyName(exprType)) {
25535
+ const nameText = getPropertyNameFromType(exprType);
25536
+ const property = getPropertyOfType(parentType, nameText);
25537
+ if (property) {
25538
+ markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
25539
+ checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, parentType!, property);
25540
+ }
25541
25541
}
25542
25542
}
25543
25543
}
0 commit comments