@@ -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,11 +6449,11 @@ namespace ts {
6448
6449
}
6449
6450
6450
6451
/**
6451
- * Gets the symbolic name for a late-bound member from its type.
6452
+ * Gets the symbolic name for a member from its type.
6452
6453
*/
6453
- function getLateBoundNameFromType (type: StringLiteralType | NumberLiteralType | UniqueESSymbolType): __String {
6454
+ function getPropertyNameFromType (type: StringLiteralType | NumberLiteralType | UniqueESSymbolType): __String {
6454
6455
if (type.flags & TypeFlags.UniqueESSymbol) {
6455
- return `__@${type.symbol.escapedName}@${getSymbolId( type.symbol)}` as __String ;
6456
+ return (<UniqueESSymbolType> type).escapedName ;
6456
6457
}
6457
6458
if (type.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
6458
6459
return escapeLeadingUnderscores("" + (<StringLiteralType | NumberLiteralType>type).value);
@@ -6518,8 +6519,8 @@ namespace ts {
6518
6519
// fall back to the early-bound name of this member.
6519
6520
links.resolvedSymbol = decl.symbol;
6520
6521
const type = checkComputedPropertyName(decl.name);
6521
- if (isTypeUsableAsLateBoundName (type)) {
6522
- const memberName = getLateBoundNameFromType (type);
6522
+ if (isTypeUsableAsPropertyName (type)) {
6523
+ const memberName = getPropertyNameFromType (type);
6523
6524
const symbolFlags = decl.symbol.flags;
6524
6525
6525
6526
// Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations.
@@ -7168,8 +7169,8 @@ namespace ts {
7168
7169
const propType = instantiateType(templateType, templateMapper);
7169
7170
// If the current iteration type constituent is a string literal type, create a property.
7170
7171
// Otherwise, for type string create a string index signature.
7171
- if (t.flags & TypeFlags.StringOrNumberLiteralOrUnique ) {
7172
- const propName = getLateBoundNameFromType(t as LiteralType );
7172
+ if (isTypeUsableAsPropertyName(t) ) {
7173
+ const propName = getPropertyNameFromType(t );
7173
7174
const modifiersProp = getPropertyOfType(modifiersType, propName);
7174
7175
const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional ||
7175
7176
!(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional);
@@ -7354,7 +7355,8 @@ namespace ts {
7354
7355
function isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes): boolean {
7355
7356
const list = obj.properties as NodeArray<ObjectLiteralElementLike | JsxAttributeLike>;
7356
7357
return list.some(property => {
7357
- const name = property.name && getTextOfPropertyName(property.name);
7358
+ const nameType = property.name && getLiteralTypeFromPropertyName(property.name);
7359
+ const name = nameType && isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
7358
7360
const expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
7359
7361
return !!expected && isLiteralType(expected) && !isTypeIdenticalTo(getTypeOfNode(property), expected);
7360
7362
});
@@ -9722,8 +9724,8 @@ namespace ts {
9722
9724
9723
9725
function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean, missingType: Type) {
9724
9726
const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined;
9725
- const propName = isTypeUsableAsLateBoundName (indexType) ?
9726
- getLateBoundNameFromType (indexType) :
9727
+ const propName = isTypeUsableAsPropertyName (indexType) ?
9728
+ getPropertyNameFromType (indexType) :
9727
9729
accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
9728
9730
getPropertyNameForKnownSymbolName(idText((<PropertyAccessExpression>accessExpression.argumentExpression).name)) :
9729
9731
accessNode && isPropertyName(accessNode) ?
@@ -10413,6 +10415,7 @@ namespace ts {
10413
10415
function createUniqueESSymbolType(symbol: Symbol) {
10414
10416
const type = <UniqueESSymbolType>createType(TypeFlags.UniqueESSymbol);
10415
10417
type.symbol = symbol;
10418
+ type.escapedName = `__@${type.symbol.escapedName}@${getSymbolId(type.symbol)}` as __String;
10416
10419
return type;
10417
10420
}
10418
10421
@@ -11300,7 +11303,7 @@ namespace ts {
11300
11303
}
11301
11304
if (resultObj.error) {
11302
11305
const reportedDiag = resultObj.error;
11303
- const propertyName = isTypeUsableAsLateBoundName (nameType) ? getLateBoundNameFromType (nameType) : undefined;
11306
+ const propertyName = isTypeUsableAsPropertyName (nameType) ? getPropertyNameFromType (nameType) : undefined;
11304
11307
const targetProp = propertyName !== undefined ? getPropertyOfType(target, propertyName) : undefined;
11305
11308
11306
11309
let issuedElaboration = false;
@@ -15172,7 +15175,9 @@ namespace ts {
15172
15175
}
15173
15176
15174
15177
function getTypeOfDestructuredProperty(type: Type, name: PropertyName) {
15175
- const text = getTextOfPropertyName(name);
15178
+ const nameType = getLiteralTypeFromPropertyName(name);
15179
+ if (!isTypeUsableAsPropertyName(nameType)) return errorType;
15180
+ const text = getPropertyNameFromType(nameType);
15176
15181
return getConstraintForLocation(getTypeOfPropertyOfType(type, text), name) ||
15177
15182
isNumericLiteralName(text) && getIndexTypeOfType(type, IndexKind.Number) ||
15178
15183
getIndexTypeOfType(type, IndexKind.String) ||
@@ -17304,9 +17309,10 @@ namespace ts {
17304
17309
const parentDeclaration = declaration.parent.parent;
17305
17310
const name = declaration.propertyName || declaration.name;
17306
17311
const parentType = getContextualTypeForVariableLikeDeclaration(parentDeclaration);
17307
- if (parentType && !isBindingPattern(name)) {
17308
- const text = getTextOfPropertyName(name);
17309
- if (text !== undefined) {
17312
+ if (parentType && !isBindingPattern(name) && !isComputedNonLiteralName(name)) {
17313
+ const nameType = getLiteralTypeFromPropertyName(name);
17314
+ if (isTypeUsableAsPropertyName(nameType)) {
17315
+ const text = getPropertyNameFromType(nameType);
17310
17316
return getTypeOfPropertyOfType(parentType, text);
17311
17317
}
17312
17318
}
@@ -18263,10 +18269,9 @@ namespace ts {
18263
18269
}
18264
18270
}
18265
18271
typeFlags |= type.flags;
18266
- const nameType = computedNameType && computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique ?
18267
- <LiteralType | UniqueESSymbolType>computedNameType : undefined;
18272
+ const nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
18268
18273
const prop = nameType ?
18269
- createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType (nameType), CheckFlags.Late) :
18274
+ createSymbol(SymbolFlags.Property | member.flags, getPropertyNameFromType (nameType), CheckFlags.Late) :
18270
18275
createSymbol(SymbolFlags.Property | member.flags, member.escapedName);
18271
18276
if (nameType) {
18272
18277
prop.nameType = nameType;
@@ -22315,15 +22320,15 @@ namespace ts {
22315
22320
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: NodeArray<ObjectLiteralElementLike>, rightIsThis = false) {
22316
22321
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
22317
22322
const name = property.name;
22318
- const text = getTextOfPropertyName(name);
22319
- if (text) {
22323
+ const exprType = getLiteralTypeFromPropertyName(name);
22324
+ if (isTypeUsableAsPropertyName(exprType)) {
22325
+ const text = getPropertyNameFromType(exprType);
22320
22326
const prop = getPropertyOfType(objectLiteralType, text);
22321
22327
if (prop) {
22322
22328
markPropertyAsReferenced(prop, property, rightIsThis);
22323
22329
checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop);
22324
22330
}
22325
22331
}
22326
- const exprType = getLiteralTypeFromPropertyName(name);
22327
22332
const elementType = getIndexedAccessType(objectLiteralType, exprType, name);
22328
22333
const type = getFlowTypeOfDestructuring(property, elementType);
22329
22334
return checkDestructuringAssignment(property.kind === SyntaxKind.ShorthandPropertyAssignment ? property : property.initializer, type);
@@ -25638,13 +25643,14 @@ namespace ts {
25638
25643
const parent = node.parent.parent;
25639
25644
const parentType = getTypeForBindingElementParent(parent);
25640
25645
const name = node.propertyName || node.name;
25641
- if (!isBindingPattern(name)) {
25642
- const nameText = getTextOfPropertyName(name);
25643
- if (nameText) {
25644
- const property = getPropertyOfType(parentType!, nameText); // TODO: GH#18217
25646
+ if (!isBindingPattern(name) && parentType) {
25647
+ const exprType = getLiteralTypeFromPropertyName(name);
25648
+ if (isTypeUsableAsPropertyName(exprType)) {
25649
+ const nameText = getPropertyNameFromType(exprType);
25650
+ const property = getPropertyOfType(parentType, nameText);
25645
25651
if (property) {
25646
25652
markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
25647
- checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, parentType! , property);
25653
+ checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, parentType, property);
25648
25654
}
25649
25655
}
25650
25656
}
0 commit comments