From 95dc8133163277f7def07e5530972555b8c18a29 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 31 May 2021 12:28:35 -0700 Subject: [PATCH 01/56] Switch index signature storage to 'indexInfos: IndexInfo[]' property --- src/compiler/checker.ts | 587 ++++++++---------- src/compiler/symbolWalker.ts | 10 +- src/compiler/types.ts | 16 +- .../fixClassIncorrectlyImplementsInterface.ts | 2 +- src/services/codefixes/inferFromUsage.ts | 26 +- src/services/codefixes/returnValueCorrect.ts | 5 +- 6 files changed, 292 insertions(+), 354 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6f6e390320b7b..5c878e5d89d90 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -413,9 +413,9 @@ namespace ts { return lexicallyScopedIdentifier ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) : undefined; }, getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)), - getIndexInfoOfType, + getIndexInfoOfType: (type, kind) => getIndexInfoOfType(type, kind === IndexKind.String ? stringType : numberType), getSignaturesOfType, - getIndexTypeOfType, + getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === IndexKind.String ? stringType : numberType), getBaseTypes, getBaseTypeOfLiteralType, getWidenedType, @@ -579,7 +579,6 @@ namespace ts { resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, - getIndexTypeOfStructuredType, getConstraintOfTypeParameter, getFirstIdentifier, getTypeArguments, @@ -775,25 +774,25 @@ namespace ts { const restrictiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(t as TypeParameter) : t); const permissiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? wildcardType : t); - const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + const emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); emptyJsxObjectType.objectFlags |= ObjectFlags.JsxAttributes; const emptyTypeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); emptyTypeLiteralSymbol.members = createSymbolTable(); - const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, emptyArray); - const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined) as ObjectType as GenericType; + const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray) as ObjectType as GenericType; emptyGenericType.instantiations = new Map(); - const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. anyFunctionType.objectFlags |= ObjectFlags.NonInferrableType; - const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const resolvingDefaultType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + const resolvingDefaultType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); const markerSuperType = createTypeParameter(); const markerSubType = createTypeParameter(); @@ -807,7 +806,7 @@ namespace ts { const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); - const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); + const enumNumberIndexInfo = createIndexInfo(numberType, stringType, /*isReadonly*/ true); const iterationTypesCache = new Map(); // cache for common IterationTypes instances const noIterationTypes: IterationTypes = { @@ -3471,7 +3470,7 @@ namespace ts { if (symbol.members) result.members = new Map(symbol.members); if (symbol.exports) result.exports = new Map(symbol.exports); const resolvedModuleType = resolveStructuredTypeMembers(moduleType as StructuredType); // Should already be resolved from the signature checks above - result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo); + result.type = createAnonymousType(result, resolvedModuleType.members, emptyArray, emptyArray, resolvedModuleType.indexInfos); return result; } } @@ -3848,8 +3847,7 @@ namespace ts { type.properties = undefined; type.callSignatures = undefined; type.constructSignatures = undefined; - type.stringIndexInfo = undefined; - type.numberIndexInfo = undefined; + type.indexInfos = undefined; return type; } @@ -3891,22 +3889,21 @@ namespace ts { return index ? concatenate(result, [index]) : result; } - function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { + function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], indexInfos: readonly IndexInfo[]): ResolvedType { const resolved = type as ResolvedType; resolved.members = members; resolved.properties = emptyArray; resolved.callSignatures = callSignatures; resolved.constructSignatures = constructSignatures; - resolved.stringIndexInfo = stringIndexInfo; - resolved.numberIndexInfo = numberIndexInfo; + resolved.indexInfos = indexInfos; // This can loop back to getPropertyOfType() which would crash if `callSignatures` & `constructSignatures` are not initialized. if (members !== emptySymbols) resolved.properties = getNamedMembers(members); return resolved; } - function createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { + function createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], indexInfos: readonly IndexInfo[]): ResolvedType { return setStructuredTypeMembers(createObjectType(ObjectFlags.Anonymous, symbol), - members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + members, callSignatures, constructSignatures, indexInfos); } function getResolvedTypeWithoutAbstractConstructSignatures(type: ResolvedType) { @@ -3919,8 +3916,7 @@ namespace ts { type.members, type.callSignatures, some(constructSignatures) ? constructSignatures : emptyArray, - type.stringIndexInfo, - type.numberIndexInfo); + type.indexInfos); type.objectTypeWithoutAbstractConstructSignatures = typeCopy; typeCopy.objectTypeWithoutAbstractConstructSignatures = typeCopy; return typeCopy; @@ -4456,8 +4452,8 @@ namespace ts { return { typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)), - indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => - withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context, /*typeNode*/ undefined)), + indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => + withContext(enclosingDeclaration, flags, tracker, context => indexInfoToIndexSignatureDeclarationHelper(indexInfo, context, /*typeNode*/ undefined)), signatureToSignatureDeclaration: (signature: Signature, kind: SignatureDeclaration["kind"], enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => signatureToSignatureDeclarationHelper(signature, kind, context)), symbolToEntityName: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => @@ -4931,7 +4927,7 @@ namespace ts { } const resolved = resolveStructuredTypeMembers(type); - if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { + if (!resolved.properties.length && !resolved.indexInfos.length) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { context.approximateLength += 2; return setEmitFlags(factory.createTypeLiteralNode(/*members*/ undefined), EmitFlags.SingleLine); @@ -4958,8 +4954,7 @@ namespace ts { const typeElementCount = resolved.callSignatures.length + (resolved.constructSignatures.length - abstractSignatures.length) + - (resolved.stringIndexInfo ? 1 : 0) + - (resolved.numberIndexInfo ? 1 : 0) + + resolved.indexInfos.length + // exclude `prototype` when writing a class expression as a type literal, as per // the logic in `createTypeNodesFromResolvedType`. (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral ? @@ -5155,22 +5150,8 @@ namespace ts { if (signature.flags & SignatureFlags.Abstract) continue; typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context) as ConstructSignatureDeclaration); } - if (resolvedType.stringIndexInfo) { - let indexSignature: IndexSignatureDeclaration; - if (resolvedType.objectFlags & ObjectFlags.ReverseMapped) { - indexSignature = indexInfoToIndexSignatureDeclarationHelper( - createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), - IndexKind.String, - context, - createElidedInformationPlaceholder(context)); - } - else { - indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context, /*typeNode*/ undefined); - } - typeElements.push(indexSignature); - } - if (resolvedType.numberIndexInfo) { - typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context, /*typeNode*/ undefined)); + for (const info of resolvedType.indexInfos) { + typeElements.push(indexInfoToIndexSignatureDeclarationHelper(info, context, resolvedType.objectFlags & ObjectFlags.ReverseMapped ? createElidedInformationPlaceholder(context) : undefined)); } const properties = resolvedType.properties; @@ -5372,9 +5353,9 @@ namespace ts { || !!a.aliasSymbol && a.aliasSymbol === b.aliasSymbol; } - function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, kind: IndexKind, context: NodeBuilderContext, typeNode: TypeNode | undefined): IndexSignatureDeclaration { + function indexInfoToIndexSignatureDeclarationHelper(indexInfo: IndexInfo, context: NodeBuilderContext, typeNode: TypeNode | undefined): IndexSignatureDeclaration { const name = getNameFromIndexInfo(indexInfo) || "x"; - const indexerTypeNode = factory.createKeywordTypeNode(kind === IndexKind.String ? SyntaxKind.StringKeyword : SyntaxKind.NumberKeyword); + const indexerTypeNode = typeToTypeNodeHelper(indexInfo.keyType, context); const indexingParameter = factory.createParameterDeclaration( /*decorators*/ undefined, @@ -7424,8 +7405,7 @@ namespace ts { // whose input is not type annotated (if the input symbol has an annotation we can reuse, we should prefer it) const ctxSrc = getSourceFileOfNode(context.enclosingDeclaration); return getObjectFlags(typeToSerialize) & (ObjectFlags.Anonymous | ObjectFlags.Mapped) && - !getIndexInfoOfType(typeToSerialize, IndexKind.String) && - !getIndexInfoOfType(typeToSerialize, IndexKind.Number) && + !length(getIndexInfosOfType(typeToSerialize)) && !isClassInstanceSide(typeToSerialize) && // While a class instance is potentially representable as a NS, prefer printing a reference to the instance type and serializing the class !!(length(filter(getPropertiesOfType(typeToSerialize), isNamespaceMember)) || length(getSignaturesOfType(typeToSerialize, SignatureKind.Call))) && !length(getSignaturesOfType(typeToSerialize, SignatureKind.Construct)) && // TODO: could probably serialize as function + ns + class, now that that's OK @@ -7616,19 +7596,16 @@ namespace ts { function serializeIndexSignatures(input: Type, baseType: Type | undefined) { const results: IndexSignatureDeclaration[] = []; - for (const type of [IndexKind.String, IndexKind.Number]) { - const info = getIndexInfoOfType(input, type); - if (info) { - if (baseType) { - const baseInfo = getIndexInfoOfType(baseType, type); - if (baseInfo) { - if (isTypeIdenticalTo(info.type, baseInfo.type)) { - continue; // elide identical index signatures - } + for (const info of getIndexInfosOfType(input)) { + if (baseType) { + const baseInfo = getIndexInfoOfType(baseType, info.keyType); + if (baseInfo) { + if (isTypeIdenticalTo(info.type, baseInfo.type)) { + continue; // elide identical index signatures } } - results.push(indexInfoToIndexSignatureDeclarationHelper(info, type, context, /*typeNode*/ undefined)); } + results.push(indexInfoToIndexSignatureDeclarationHelper(info, context, /*typeNode*/ undefined)); } return results; } @@ -8149,7 +8126,7 @@ namespace ts { } function getTypeOfPropertyOrIndexSignature(type: Type, name: __String): Type { - return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, IndexKind.Number) || getIndexTypeOfType(type, IndexKind.String) || unknownType; + return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, numberType) || getIndexTypeOfType(type, stringType) || unknownType; } function isTypeAny(type: Type | undefined) { @@ -8191,9 +8168,7 @@ namespace ts { members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false)); } } - const stringIndexInfo = getIndexInfoOfType(source, IndexKind.String); - const numberIndexInfo = getIndexInfoOfType(source, IndexKind.Number); - const result = createAnonymousType(symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + const result = createAnonymousType(symbol, members, emptyArray, emptyArray, getIndexInfosOfType(source)); result.objectFlags |= ObjectFlags.ObjectRestType; return result; } @@ -8660,7 +8635,7 @@ namespace ts { if (s?.exports?.size) { mergeSymbolTable(exports, s.exports); } - const type = createAnonymousType(symbol, exports, emptyArray, emptyArray, undefined, undefined); + const type = createAnonymousType(symbol, exports, emptyArray, emptyArray, emptyArray); type.objectFlags |= ObjectFlags.JSLiteral; return type; } @@ -8770,8 +8745,7 @@ namespace ts { members, exportedType.callSignatures, exportedType.constructSignatures, - exportedType.stringIndexInfo, - exportedType.numberIndexInfo); + exportedType.indexInfos); result.objectFlags |= (getObjectFlags(type) & ObjectFlags.JSLiteral); // Propagate JSLiteral flag if (result.symbol && result.symbol.flags & SymbolFlags.Class && type === getDeclaredTypeOfClassOrInterface(result.symbol)) { result.objectFlags |= ObjectFlags.IsClassInstanceClone; // Propagate the knowledge that this type is equivalent to the symbol's class instance type @@ -8842,7 +8816,7 @@ namespace ts { forEach(pattern.elements, e => { const name = e.propertyName || e.name as Identifier; if (e.dotDotDotToken) { - stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); + stringIndexInfo = createIndexInfo(stringType, anyType, /*isReadonly*/ false); return; } @@ -8859,7 +8833,7 @@ namespace ts { symbol.bindingElement = e; members.set(symbol.escapedName, symbol); }); - const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, undefined); + const result = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo ? [stringIndexInfo] : emptyArray); result.objectFlags |= objectFlags; if (includePatternInType) { result.pattern = pattern; @@ -8997,7 +8971,7 @@ namespace ts { if (fileSymbol.exports) result.exports = new Map(fileSymbol.exports); const members = createSymbolTable(); members.set("exports" as __String, result); - return createAnonymousType(symbol, members, emptyArray, emptyArray, undefined, undefined); + return createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray); } // Handle catch clause variables Debug.assertIsDefined(symbol.valueDeclaration); @@ -10145,11 +10119,11 @@ namespace ts { // Start with signatures at empty array in case of recursive types (type as InterfaceTypeWithDeclaredMembers).declaredCallSignatures = emptyArray; (type as InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = emptyArray; + (type as InterfaceTypeWithDeclaredMembers).declaredIndexInfos = emptyArray; (type as InterfaceTypeWithDeclaredMembers).declaredCallSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call)); (type as InterfaceTypeWithDeclaredMembers).declaredConstructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New)); - (type as InterfaceTypeWithDeclaredMembers).declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.String); - (type as InterfaceTypeWithDeclaredMembers).declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.Number); + (type as InterfaceTypeWithDeclaredMembers).declaredIndexInfos = getIndexInfosOfSymbol(symbol); } return type as InterfaceTypeWithDeclaredMembers; } @@ -10414,45 +10388,38 @@ namespace ts { let mapper: TypeMapper | undefined; let members: SymbolTable; let callSignatures: readonly Signature[]; - let constructSignatures: readonly Signature[] | undefined; - let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; + let constructSignatures: readonly Signature[]; + let indexInfos: readonly IndexInfo[]; if (rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) { members = source.symbol ? getMembersOfSymbol(source.symbol) : createSymbolTable(source.declaredProperties); callSignatures = source.declaredCallSignatures; constructSignatures = source.declaredConstructSignatures; - stringIndexInfo = source.declaredStringIndexInfo; - numberIndexInfo = source.declaredNumberIndexInfo; + indexInfos = source.declaredIndexInfos; } else { mapper = createTypeMapper(typeParameters, typeArguments); members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1); callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper); constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper); - stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper); - numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper); + indexInfos = instantiateIndexInfos(source.declaredIndexInfos, mapper); } const baseTypes = getBaseTypes(source); if (baseTypes.length) { if (source.symbol && members === getMembersOfSymbol(source.symbol)) { members = createSymbolTable(source.declaredProperties); } - setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); const thisArgument = lastOrUndefined(typeArguments); for (const baseType of baseTypes) { const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType)); callSignatures = concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Call)); constructSignatures = concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Construct)); - if (!stringIndexInfo) { - stringIndexInfo = instantiatedBaseType === anyType ? - createIndexInfo(anyType, /*isReadonly*/ false) : - getIndexInfoOfType(instantiatedBaseType, IndexKind.String); - } - numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, IndexKind.Number); + const inheritedIndexInfos = instantiatedBaseType !== anyType ? getIndexInfosOfType(instantiatedBaseType) : [createIndexInfo(stringType, anyType, /*isReadonly*/ false)]; + indexInfos = concatenate(indexInfos, filter(inheritedIndexInfos, info => !findIndexInfo(indexInfos, info.keyType))); } } - setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); } function resolveClassOrInterfaceMembers(type: InterfaceType): void { @@ -10791,18 +10758,20 @@ namespace ts { return result; } - function getUnionIndexInfo(types: readonly Type[], kind: IndexKind): IndexInfo | undefined { - const indexTypes: Type[] = []; - let isAnyReadonly = false; - for (const type of types) { - const indexInfo = getIndexInfoOfType(getApparentType(type), kind); - if (!indexInfo) { - return undefined; + function getUnionIndexInfos(types: readonly Type[]): IndexInfo[] { + const sourceInfos = getIndexInfosOfType(types[0]); + if (sourceInfos) { + const result = []; + for (const info of sourceInfos) { + const indexType = info.keyType; + if (every(types, t => !!getIndexInfoOfType(t, indexType))) { + result.push(createIndexInfo(indexType, getUnionType(map(types, t => getIndexTypeOfType(t, indexType)!)), + some(types, t => getIndexInfoOfType(t, indexType)!.isReadonly))); + } } - indexTypes.push(indexInfo.type); - isAnyReadonly = isAnyReadonly || indexInfo.isReadonly; + return result; } - return createIndexInfo(getUnionType(indexTypes, UnionReduction.Subtype), isAnyReadonly); + return emptyArray; } function resolveUnionTypeMembers(type: UnionType) { @@ -10810,9 +10779,8 @@ namespace ts { // type use getPropertiesOfType (only the language service uses this). const callSignatures = getUnionSignatures(map(type.types, t => t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, SignatureKind.Call))); const constructSignatures = getUnionSignatures(map(type.types, t => getSignaturesOfType(t, SignatureKind.Construct))); - const stringIndexInfo = getUnionIndexInfo(type.types, IndexKind.String); - const numberIndexInfo = getUnionIndexInfo(type.types, IndexKind.Number); - setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + const indexInfos = getUnionIndexInfos(type.types); + setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, indexInfos); } function intersectTypes(type1: Type, type2: Type): Type; @@ -10821,16 +10789,6 @@ namespace ts { return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]); } - function intersectIndexInfos(info1: IndexInfo | undefined, info2: IndexInfo | undefined): IndexInfo | undefined { - return !info1 ? info2 : !info2 ? info1 : createIndexInfo( - getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly); - } - - function unionSpreadIndexInfos(info1: IndexInfo | undefined, info2: IndexInfo | undefined): IndexInfo | undefined { - return info1 && info2 && createIndexInfo( - getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly); - } - function findMixins(types: readonly Type[]): readonly boolean[] { const constructorTypeCount = countWhere(types, (t) => getSignaturesOfType(t, SignatureKind.Construct).length > 0); const mixinFlags = map(types, isMixinConstructorType); @@ -10859,8 +10817,7 @@ namespace ts { // intersection type use getPropertiesOfType (only the language service uses this). let callSignatures: Signature[] | undefined; let constructSignatures: Signature[] | undefined; - let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; + let indexInfos: IndexInfo[] | undefined; const types = type.types; const mixinFlags = findMixins(types); const mixinCount = countWhere(mixinFlags, (b) => b); @@ -10883,10 +10840,9 @@ namespace ts { constructSignatures = appendSignatures(constructSignatures, signatures); } callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); - stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String)); - numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number)); + indexInfos = reduceLeft(getIndexInfosOfType(t), appendIndexInfo, indexInfos); } - setStructuredTypeMembers(type, emptySymbols, callSignatures || emptyArray, constructSignatures || emptyArray, stringIndexInfo, numberIndexInfo); + setStructuredTypeMembers(type, emptySymbols, callSignatures || emptyArray, constructSignatures || emptyArray, indexInfos || emptyArray); } function appendSignatures(signatures: Signature[] | undefined, newSignatures: readonly Signature[]) { @@ -10898,34 +10854,44 @@ namespace ts { return signatures; } + function appendIndexInfo(indexInfos: IndexInfo[] | undefined, newInfo: IndexInfo) { + if (indexInfos) { + for (let i = 0; i < indexInfos.length; i++) { + const info = indexInfos[i]; + if (info.keyType === newInfo.keyType) { + indexInfos[i] = createIndexInfo(info.keyType, getIntersectionType([info.type, newInfo.type]), info.isReadonly && newInfo.isReadonly); + return indexInfos; + } + } + } + return append(indexInfos, newInfo); + } + /** * Converts an AnonymousType to a ResolvedType. */ function resolveAnonymousTypeMembers(type: AnonymousType) { const symbol = getMergedSymbol(type.symbol); if (type.target) { - setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined); + setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper!, /*mappingThisOnly*/ false); const callSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Call), type.mapper!); const constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper!); - const stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, IndexKind.String), type.mapper!); - const numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, IndexKind.Number), type.mapper!); - setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + const indexInfos = instantiateIndexInfos(getIndexInfosOfType(type.target), type.mapper!); + setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); } else if (symbol.flags & SymbolFlags.TypeLiteral) { - setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined); + setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); const members = getMembersOfSymbol(symbol); const callSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call)); const constructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New)); - const stringIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.String); - const numberIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.Number); - setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + const indexInfos = getIndexInfosOfSymbol(symbol); + setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); } else { // Combinations of function, class, enum and module let members = emptySymbols; - let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; + let indexInfos: IndexInfo[] | undefined; if (symbol.exports) { members = getExportsOfSymbol(symbol); if (symbol === globalThisSymbol) { @@ -10939,7 +10905,7 @@ namespace ts { } } let baseConstructorIndexInfo: IndexInfo | undefined; - setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); + setStructuredTypeMembers(type, members, emptyArray, emptyArray, emptyArray); if (symbol.flags & SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); const baseConstructorType = getBaseConstructorTypeOfClass(classType); @@ -10948,23 +10914,24 @@ namespace ts { addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } else if (baseConstructorType === anyType) { - baseConstructorIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); + baseConstructorIndexInfo = createIndexInfo(stringType, anyType, /*isReadonly*/ false); } } const indexSymbol = getIndexSymbolFromSymbolTable(members); if (indexSymbol) { - stringIndexInfo = getIndexInfoOfIndexSymbol(indexSymbol, IndexKind.String); - numberIndexInfo = getIndexInfoOfIndexSymbol(indexSymbol, IndexKind.Number); + indexInfos = getIndexInfosOfIndexSymbol(indexSymbol); } else { - stringIndexInfo = baseConstructorIndexInfo; + if (baseConstructorIndexInfo) { + indexInfos = append(indexInfos, baseConstructorIndexInfo); + } if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum || some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) { - numberIndexInfo = enumNumberIndexInfo; + indexInfos = append(indexInfos, enumNumberIndexInfo); } } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos || emptyArray); // We resolve the members before computing the signatures because a signature may use // typeof with a qualified name expression that circularly references the type we are // in the process of resolving (see issue #6072). The temporarily empty signature list @@ -10999,19 +10966,12 @@ namespace ts { return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getLiteralType(0), createTupleType([replacement])])); } - function getIndexInfoOfIndexSymbol(indexSymbol: Symbol, indexKind: IndexKind) { - const declaration = getIndexDeclarationOfIndexSymbol(indexSymbol, indexKind); - if (!declaration) return undefined; - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration); - } - function resolveReverseMappedTypeMembers(type: ReverseMappedType) { - const indexInfo = getIndexInfoOfType(type.source, IndexKind.String); + const indexInfo = getIndexInfoOfType(type.source, stringType); const modifiers = getMappedTypeModifiers(type.mappedType); const readonlyMask = modifiers & MappedTypeModifiers.IncludeReadonly ? false : true; const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; - const stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly); + const indexInfos = indexInfo ? [createIndexInfo(stringType, inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly)] : emptyArray; const members = createSymbolTable(); for (const prop of getPropertiesOfType(type.source)) { const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); @@ -11036,7 +10996,7 @@ namespace ts { } members.set(prop.escapedName, inferredProp); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); + setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos); } // Return the lower bound of the key type in a mapped type. Intuitively, the lower @@ -11076,7 +11036,7 @@ namespace ts { let stringIndexInfo: IndexInfo | undefined; let numberIndexInfo: IndexInfo | undefined; // Resolve upfront such that recursive references see an empty object type. - setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined); + setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type, // and T as the template type. const typeParameter = getTypeParameterFromMappedType(type); @@ -11091,17 +11051,17 @@ namespace ts { for (const prop of getPropertiesOfType(modifiersType)) { addMemberForKeyType(getLiteralTypeFromProperty(prop, include)); } - if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { + if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, stringType)) { addMemberForKeyType(stringType); } - if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, IndexKind.Number)) { + if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, numberType)) { addMemberForKeyType(numberType); } } else { forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + setStructuredTypeMembers(type, members, emptyArray, emptyArray, createIndexInfoArray(stringIndexInfo, numberIndexInfo)); function addMemberForKeyType(keyType: Type) { const propNameType = nameType ? instantiateType(nameType, appendTypeMapping(type.mapper, typeParameter, keyType)) : keyType; @@ -11144,11 +11104,11 @@ namespace ts { else if (propNameType.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) { const propType = instantiateType(templateType, appendTypeMapping(type.mapper, typeParameter, keyType)); if (propNameType.flags & (TypeFlags.Any | TypeFlags.String)) { - stringIndexInfo = createIndexInfo(stringIndexInfo ? getUnionType([stringIndexInfo.type, propType]) : propType, + stringIndexInfo = createIndexInfo(stringType, stringIndexInfo ? getUnionType([stringIndexInfo.type, propType]) : propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); } else { - numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType, + numberIndexInfo = createIndexInfo(numberType, numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); } } @@ -11323,7 +11283,7 @@ namespace ts { } // The properties of a union type are those that are present in all constituent types, so // we only need to check the properties of the first type without index signature - if (type.flags & TypeFlags.Union && !getIndexInfoOfType(current, IndexKind.String) && !getIndexInfoOfType(current, IndexKind.Number)) { + if (type.flags & TypeFlags.Union && !getIndexInfoOfType(current, stringType) && !getIndexInfoOfType(current, numberType)) { break; } } @@ -11769,7 +11729,7 @@ namespace ts { } } else if (isUnion) { - const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number) || getIndexInfoOfType(type, IndexKind.String)); + const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, numberType) || getIndexInfoOfType(type, stringType)); if (indexInfo) { checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0); indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); @@ -12003,28 +11963,40 @@ namespace ts { return getSignaturesOfStructuredType(getReducedApparentType(type), kind); } - function getIndexInfoOfStructuredType(type: Type, kind: IndexKind): IndexInfo | undefined { + function getIndexInfosOfStructuredType(type: Type): readonly IndexInfo[] { if (type.flags & TypeFlags.StructuredType) { const resolved = resolveStructuredTypeMembers(type as ObjectType); - return kind === IndexKind.String ? resolved.stringIndexInfo : resolved.numberIndexInfo; + return resolved.indexInfos; } + return emptyArray; } - function getIndexTypeOfStructuredType(type: Type, kind: IndexKind): Type | undefined { - const info = getIndexInfoOfStructuredType(type, kind); - return info && info.type; + function findIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) { + return find(indexInfos, info => info.keyType === keyType); + } + + function getIndexInfoOfStructuredType(type: Type, keyType: Type): IndexInfo | undefined { + return findIndexInfo(getIndexInfosOfStructuredType(type), keyType); + } + + function getIndexInfosOfType(type: Type): readonly IndexInfo[] { + return getIndexInfosOfStructuredType(getReducedApparentType(type)); } // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and // maps primitive types and type parameters are to their apparent types. - function getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined { - return getIndexInfoOfStructuredType(getReducedApparentType(type), kind); + function getIndexInfoOfType(type: Type, keyType: Type): IndexInfo | undefined { + return getIndexInfoOfStructuredType(getReducedApparentType(type), keyType); } // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and // maps primitive types and type parameters are to their apparent types. - function getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined { - return getIndexTypeOfStructuredType(getReducedApparentType(type), kind); + function getIndexTypeOfType(type: Type, keyType: Type): Type | undefined { + return getIndexInfoOfStructuredType(getReducedApparentType(type), keyType)?.type; + } + + function createIndexInfoArray(info1: IndexInfo | undefined, info2: IndexInfo | undefined) { + return info1 ? info2 ? [info1, info2] : [info1] : info2 ? [info2] : emptyArray; } function getImplicitIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined { @@ -12037,7 +12009,7 @@ namespace ts { } } if (kind === IndexKind.String) { - append(propTypes, getIndexTypeOfType(type, IndexKind.Number)); + append(propTypes, getIndexTypeOfType(type, numberType)); } if (propTypes.length) { return getUnionType(propTypes); @@ -12484,7 +12456,7 @@ namespace ts { if (signatureHasRestParameter(signature)) { const sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]); const restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType; - return restType && getIndexTypeOfType(restType, IndexKind.Number); + return restType && getIndexTypeOfType(restType, numberType); } return undefined; } @@ -12586,6 +12558,7 @@ namespace ts { type.properties = emptyArray; type.callSignatures = !isConstructor ? [signature] : emptyArray; type.constructSignatures = isConstructor ? [signature] : emptyArray; + type.indexInfos = emptyArray; signature.isolatedSignatureType = type; } @@ -12600,44 +12573,37 @@ namespace ts { return symbolTable.get(InternalSymbolName.Index); } - function getIndexDeclarationOfSymbol(symbol: Symbol | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined { - const indexSymbol = symbol && getIndexSymbol(symbol); - return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind); + function createIndexInfo(keyType: Type, type: Type, isReadonly: boolean, declaration?: IndexSignatureDeclaration): IndexInfo { + return { keyType, type, isReadonly, declaration }; } - function getIndexDeclarationOfSymbolTable(symbolTable: SymbolTable | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined { - const indexSymbol = symbolTable && getIndexSymbolFromSymbolTable(symbolTable); - return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind); + function getIndexInfosOfSymbol(symbol: Symbol): IndexInfo[] { + const indexSymbol = getIndexSymbol(symbol); + return indexSymbol ? getIndexInfosOfIndexSymbol(indexSymbol) : emptyArray; } - function getIndexDeclarationOfIndexSymbol(indexSymbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { - const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword; - if (indexSymbol?.declarations) { - for (const decl of indexSymbol.declarations) { - const node = cast(decl, isIndexSignatureDeclaration); - if (node.parameters.length === 1) { - const parameter = node.parameters[0]; - if (parameter.type && parameter.type.kind === syntaxKind) { - return node; + function getIndexInfosOfIndexSymbol(indexSymbol: Symbol): IndexInfo[] { + if (indexSymbol.declarations) { + const indexInfos: IndexInfo[] = []; + for (const declaration of (indexSymbol.declarations as IndexSignatureDeclaration[])) { + if (declaration.parameters.length === 1) { + const parameter = declaration.parameters[0]; + if (parameter.type) { + const keyType = getTypeFromTypeNode(parameter.type); + if (isValidIndexKeyType(keyType) && !findIndexInfo(indexInfos, keyType)) { + indexInfos.push(createIndexInfo(keyType, declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, + hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration)); + } } } } + return indexInfos; } - - return undefined; - } - - function createIndexInfo(type: Type, isReadonly: boolean, declaration?: IndexSignatureDeclaration): IndexInfo { - return { type, isReadonly, declaration }; + return emptyArray; } - function getIndexInfoOfSymbol(symbol: Symbol, kind: IndexKind): IndexInfo | undefined { - const declaration = getIndexDeclarationOfSymbol(symbol, kind); - if (declaration) { - return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration); - } - return undefined; + function isValidIndexKeyType(type: Type) { + return !!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol)) || isPatternLiteralType(type); } function getConstraintDeclaration(type: TypeParameter): TypeNode | undefined { @@ -13120,8 +13086,8 @@ namespace ts { if (isJSDocIndexSignature(node)) { const indexed = getTypeFromTypeNode(typeArgs[0]); const target = getTypeFromTypeNode(typeArgs[1]); - const index = createIndexInfo(target, /*isReadonly*/ false); - return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexed === stringType ? index : undefined, indexed === numberType ? index : undefined); + const indexInfo = indexed === stringType || indexed === numberType ? [createIndexInfo(indexed, target, /*isReadonly*/ false)] : emptyArray; + return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexInfo); } return anyType; } @@ -13547,8 +13513,7 @@ namespace ts { type.declaredProperties = properties; type.declaredCallSignatures = emptyArray; type.declaredConstructSignatures = emptyArray; - type.declaredStringIndexInfo = undefined; - type.declaredNumberIndexInfo = undefined; + type.declaredIndexInfos = emptyArray; type.elementFlags = elementFlags; type.minLength = minLength; type.fixedLength = fixedLength; @@ -13609,7 +13574,7 @@ namespace ts { } else { // Treat everything else as an array type and create a rest element. - addElement(isArrayLikeType(type) && getIndexTypeOfType(type, IndexKind.Number) || errorType, ElementFlags.Rest, target.labeledElementDeclarations?.[i]); + addElement(isArrayLikeType(type) && getIndexTypeOfType(type, numberType) || errorType, ElementFlags.Rest, target.labeledElementDeclarations?.[i]); } } else { @@ -14388,7 +14353,7 @@ namespace ts { } function getNonEnumNumberIndexInfo(type: Type) { - const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number); + const numberIndexInfo = getIndexInfoOfType(type, numberType); return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined; } @@ -14402,8 +14367,8 @@ namespace ts { type === wildcardType ? wildcardType : type.flags & TypeFlags.Unknown ? neverType : type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType : - stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral, includeOrigin) : - !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol, includeOrigin)]) : + stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, stringType) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral, includeOrigin) : + !noIndexSignatures && getIndexInfoOfType(type, stringType) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol, includeOrigin)]) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol, includeOrigin)]) : getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique, includeOrigin); } @@ -14658,7 +14623,7 @@ namespace ts { error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType)); } } - errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, IndexKind.Number)); + errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, numberType)); return mapType(objectType, t => { const restType = getRestTypeOfTupleType(t as TupleTypeReference) || undefinedType; return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([restType, undefinedType]) : restType; @@ -14669,8 +14634,8 @@ namespace ts { if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { return objectType; } - const stringIndexInfo = getIndexInfoOfType(objectType, IndexKind.String); - const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || stringIndexInfo; + const stringIndexInfo = getIndexInfoOfType(objectType, stringType); + const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, numberType) || stringIndexInfo; if (indexInfo) { if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo === stringIndexInfo) { if (accessExpression) { @@ -14714,7 +14679,7 @@ namespace ts { const typeName = typeToString(objectType); error(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_to_access_the_static_member_2_instead, propName as string, typeName, typeName + "[" + getTextOfNode(accessExpression.argumentExpression) + "]"); } - else if (getIndexTypeOfType(objectType, IndexKind.Number)) { + else if (getIndexTypeOfType(objectType, numberType)) { error(accessExpression.argumentExpression, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number); } else { @@ -15397,13 +15362,7 @@ namespace ts { members.set(prop.escapedName, result); } } - const spread = createAnonymousType( - type.symbol, - members, - emptyArray, - emptyArray, - getIndexInfoOfType(type, IndexKind.String), - getIndexInfoOfType(type, IndexKind.Number)); + const spread = createAnonymousType(type.symbol, members, emptyArray, emptyArray, getIndexInfosOfType(type)); spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; return spread; } @@ -15468,17 +15427,7 @@ namespace ts { const members = createSymbolTable(); const skippedPrivateMembers = new Set<__String>(); - let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; - if (left === emptyObjectType) { - // for the first spread element, left === emptyObjectType, so take the right's string indexer - stringIndexInfo = getIndexInfoOfType(right, IndexKind.String); - numberIndexInfo = getIndexInfoOfType(right, IndexKind.Number); - } - else { - stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.String), getIndexInfoOfType(right, IndexKind.String)); - numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.Number), getIndexInfoOfType(right, IndexKind.Number)); - } + let indexInfos = left === emptyObjectType ? getIndexInfosOfType(right) : getUnionIndexInfos([left, right]); for (const rightProp of getPropertiesOfType(right)) { if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) { @@ -15513,13 +15462,7 @@ namespace ts { } } - const spread = createAnonymousType( - symbol, - members, - emptyArray, - emptyArray, - getIndexInfoWithReadonly(stringIndexInfo, readonly), - getIndexInfoWithReadonly(numberIndexInfo, readonly)); + const spread = createAnonymousType(symbol, members, emptyArray, emptyArray, sameMap(indexInfos, info => getIndexInfoWithReadonly(info, readonly))); spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral | ObjectFlags.ContainsSpread | objectFlags; return spread; } @@ -15545,8 +15488,8 @@ namespace ts { return result; } - function getIndexInfoWithReadonly(info: IndexInfo | undefined, readonly: boolean) { - return info && info.isReadonly !== readonly ? createIndexInfo(info.type, readonly, info.declaration) : info; + function getIndexInfoWithReadonly(info: IndexInfo, readonly: boolean) { + return info.isReadonly !== readonly ? createIndexInfo(info.keyType, info.type, readonly, info.declaration) : info; } function createLiteralType(flags: TypeFlags, value: string | number | PseudoBigInt, symbol: Symbol | undefined) { @@ -15828,6 +15771,10 @@ namespace ts { return instantiateList(signatures, mapper, instantiateSignature); } + function instantiateIndexInfos(indexInfos: readonly IndexInfo[], mapper: TypeMapper): readonly IndexInfo[] { + return instantiateList(indexInfos, mapper, instantiateIndexInfo); + } + function createTypeMapper(sources: readonly TypeParameter[], targets: readonly Type[] | undefined): TypeMapper { return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : makeArrayTypeMapper(sources, targets); } @@ -16344,8 +16291,8 @@ namespace ts { return type.restrictiveInstantiation; } - function instantiateIndexInfo(info: IndexInfo | undefined, mapper: TypeMapper): IndexInfo | undefined { - return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration); + function instantiateIndexInfo(info: IndexInfo, mapper: TypeMapper) { + return createIndexInfo(info.keyType, instantiateType(info.type, mapper), info.isReadonly, info.declaration); } // Returns true if the given expression contains (at any level of nesting) a function or arrow expression @@ -16432,6 +16379,7 @@ namespace ts { result.properties = resolved.properties; result.callSignatures = emptyArray; result.constructSignatures = emptyArray; + result.indexInfos = emptyArray; return result; } } @@ -16725,8 +16673,8 @@ namespace ts { let issuedElaboration = false; if (!targetProp) { - const indexInfo = isTypeAssignableToKind(nameType, TypeFlags.NumberLike) && getIndexInfoOfType(target, IndexKind.Number) || - getIndexInfoOfType(target, IndexKind.String) || + const indexInfo = isTypeAssignableToKind(nameType, TypeFlags.NumberLike) && getIndexInfoOfType(target, numberType) || + getIndexInfoOfType(target, stringType) || undefined; if (indexInfo && indexInfo.declaration && !getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) { issuedElaboration = true; @@ -17191,8 +17139,7 @@ namespace ts { t.properties.length === 0 && t.callSignatures.length === 0 && t.constructSignatures.length === 0 && - !t.stringIndexInfo && - !t.numberIndexInfo; + t.indexInfos.length === 0; } function isEmptyObjectType(type: Type): boolean { @@ -17210,7 +17157,7 @@ namespace ts { } function isStringIndexSignatureOnlyType(type: Type): boolean { - return type.flags & TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, IndexKind.String) && !getIndexInfoOfType(type, IndexKind.Number) || + return type.flags & TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, stringType) && !getIndexInfoOfType(type, numberType) || type.flags & TypeFlags.UnionOrIntersection && every((type as UnionOrIntersectionType).types, isStringIndexSignatureOnlyType) || false; } @@ -17924,7 +17871,7 @@ namespace ts { const appendPropType = (propTypes: Type[] | undefined, type: Type) => { type = getApparentType(type); const prop = type.flags & TypeFlags.UnionOrIntersection ? getPropertyOfUnionOrIntersectionType(type as UnionOrIntersectionType, name) : getPropertyOfObjectType(type, name); - const propType = prop && getTypeOfSymbol(prop) || isNumericLiteralName(name) && getIndexTypeOfType(type, IndexKind.Number) || getIndexTypeOfType(type, IndexKind.String) || undefinedType; + const propType = prop && getTypeOfSymbol(prop) || isNumericLiteralName(name) && getIndexTypeOfType(type, numberType) || getIndexTypeOfType(type, stringType) || undefinedType; return append(propTypes, propType); }; return getUnionType(reduceLeft(types, appendPropType, /*initial*/ undefined) || emptyArray); @@ -18718,7 +18665,7 @@ namespace ts { } else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) { if (relation !== identityRelation) { - return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors); + return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, reportErrors); } else { // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple @@ -18745,9 +18692,9 @@ namespace ts { if (result) { result &= signaturesRelatedTo(source, target, SignatureKind.Construct, reportStructuralErrors); if (result) { - result &= indexTypesRelatedTo(source, target, IndexKind.String, sourceIsPrimitive, reportStructuralErrors, intersectionState); + result &= indexTypesRelatedTo(source, target, stringType, sourceIsPrimitive, reportStructuralErrors, intersectionState); if (result) { - result &= indexTypesRelatedTo(source, target, IndexKind.Number, sourceIsPrimitive, reportStructuralErrors, intersectionState); + result &= indexTypesRelatedTo(source, target, numberType, sourceIsPrimitive, reportStructuralErrors, intersectionState); } } } @@ -18937,13 +18884,13 @@ namespace ts { if (result) { result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false); if (result) { - result &= indexTypesRelatedTo(source, type, IndexKind.String, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); + result &= indexTypesRelatedTo(source, type, stringType, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); // Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the // element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems // with index type assignability as the types for the excluded discriminants are still included // in the index type. if (result && !(isTupleType(source) && isTupleType(type))) { - result &= indexTypesRelatedTo(source, type, IndexKind.Number, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); + result &= indexTypesRelatedTo(source, type, numberType, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); } } } @@ -19424,7 +19371,7 @@ namespace ts { return result; } - function eachPropertyRelatedTo(source: Type, target: Type, kind: IndexKind, reportErrors: boolean): Ternary { + function eachPropertyRelatedTo(source: Type, target: Type, keyType: Type, reportErrors: boolean): Ternary { let result = Ternary.True; const props = source.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(source as IntersectionType) : getPropertiesOfObjectType(source); for (const prop of props) { @@ -19436,9 +19383,9 @@ namespace ts { if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) { continue; } - if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) { + if (keyType === stringType || isNumericLiteralName(prop.escapedName)) { const propType = getTypeOfSymbol(prop); - const type = propType.flags & TypeFlags.Undefined || !(kind === IndexKind.String && prop.flags & SymbolFlags.Optional) + const type = propType.flags & TypeFlags.Undefined || !(keyType === stringType && prop.flags & SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); const related = isRelatedTo(type, target, reportErrors); @@ -19462,18 +19409,18 @@ namespace ts { return related; } - function indexTypesRelatedTo(source: Type, target: Type, kind: IndexKind, sourceIsPrimitive: boolean, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function indexTypesRelatedTo(source: Type, target: Type, keyType: Type, sourceIsPrimitive: boolean, reportErrors: boolean, intersectionState: IntersectionState): Ternary { if (relation === identityRelation) { - return indexTypesIdenticalTo(source, target, kind); + return indexTypesIdenticalTo(source, target, keyType); } - const targetType = getIndexTypeOfType(target, kind); + const targetType = getIndexTypeOfType(target, keyType); if (!targetType) { return Ternary.True; } if (targetType.flags & TypeFlags.Any && !sourceIsPrimitive) { // An index signature of type `any` permits assignment from everything but primitives, // provided that there is also a `string` index signature of type `any`. - const stringIndexType = kind === IndexKind.String ? targetType : getIndexTypeOfType(target, IndexKind.String); + const stringIndexType = keyType === stringType ? targetType : getIndexTypeOfType(target, stringType); if (stringIndexType && stringIndexType.flags & TypeFlags.Any) { return Ternary.True; } @@ -19483,17 +19430,17 @@ namespace ts { // A generic mapped type { [P in K]: T } is related to a type with an index signature // { [x: string]: U }, and optionally with an index signature { [x: number]: V }, // if T is related to U and V. - return getIndexTypeOfType(target, IndexKind.String) ? isRelatedTo(getTemplateTypeFromMappedType(source), targetType, reportErrors) : Ternary.False; + return getIndexTypeOfType(target, stringType) ? isRelatedTo(getTemplateTypeFromMappedType(source), targetType, reportErrors) : Ternary.False; } - const indexType = getIndexTypeOfType(source, kind) || kind === IndexKind.Number && getIndexTypeOfType(source, IndexKind.String); + const indexType = getIndexTypeOfType(source, keyType) || keyType === numberType && getIndexTypeOfType(source, stringType); if (indexType) { return indexTypeRelatedTo(indexType, targetType, reportErrors); } if (!(intersectionState & IntersectionState.Source) && isObjectTypeWithInferableIndex(source)) { // Intersection constituents are never considered to have an inferred index signature - let related = eachPropertyRelatedTo(source, targetType, kind, reportErrors); - if (related && kind === IndexKind.String) { - const numberIndexType = getIndexTypeOfType(source, IndexKind.Number); + let related = eachPropertyRelatedTo(source, targetType, keyType, reportErrors); + if (related && keyType === stringType) { + const numberIndexType = getIndexTypeOfType(source, numberType); if (numberIndexType) { related &= indexTypeRelatedTo(numberIndexType, targetType, reportErrors); } @@ -19506,9 +19453,9 @@ namespace ts { return Ternary.False; } - function indexTypesIdenticalTo(source: Type, target: Type, indexKind: IndexKind): Ternary { - const targetInfo = getIndexInfoOfType(target, indexKind); - const sourceInfo = getIndexInfoOfType(source, indexKind); + function indexTypesIdenticalTo(source: Type, target: Type, keyType: Type): Ternary { + const targetInfo = getIndexInfoOfType(target, keyType); + const sourceInfo = getIndexInfoOfType(source, keyType); if (!sourceInfo && !targetInfo) { return Ternary.True; } @@ -19624,10 +19571,8 @@ namespace ts { function isWeakType(type: Type): boolean { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type as ObjectType); - return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && - !resolved.stringIndexInfo && !resolved.numberIndexInfo && - resolved.properties.length > 0 && - every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); + return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && resolved.indexInfos.length === 0 && + resolved.properties.length > 0 && every(resolved.properties, p => !!(p.flags & SymbolFlags.Optional)); } if (type.flags & TypeFlags.Intersection) { return every((type as IntersectionType).types, isWeakType); @@ -20443,12 +20388,7 @@ namespace ts { const resolved = type as ResolvedType; const members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); - const regularNew = createAnonymousType(resolved.symbol, - members, - resolved.callSignatures, - resolved.constructSignatures, - resolved.stringIndexInfo, - resolved.numberIndexInfo); + const regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.indexInfos); regularNew.flags = resolved.flags; regularNew.objectFlags |= resolved.objectFlags & ~ObjectFlags.FreshLiteral; (type as FreshObjectLiteralType).regularType = regularNew; @@ -20527,11 +20467,8 @@ namespace ts { } } } - const stringIndexInfo = getIndexInfoOfType(type, IndexKind.String); - const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number); const result = createAnonymousType(type.symbol, members, emptyArray, emptyArray, - stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), - numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly)); + sameMap(getIndexInfosOfType(type), info => createIndexInfo(info.keyType, getWidenedType(info.type), info.isReadonly))); result.objectFlags |= (getObjectFlags(type) & (ObjectFlags.JSLiteral | ObjectFlags.NonInferrableType)); // Retain js literal flag through widening return result; } @@ -20863,8 +20800,8 @@ namespace ts { } members.set(name, literalProp); }); - const indexInfo = type.flags & TypeFlags.String ? createIndexInfo(emptyObjectType, /*isReadonly*/ false) : undefined; - return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined); + const indexInfos = type.flags & TypeFlags.String ? [createIndexInfo(stringType, emptyObjectType, /*isReadonly*/ false)] : emptyArray; + return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfos); } /** @@ -20901,7 +20838,7 @@ namespace ts { function createReverseMappedType(source: Type, target: MappedType, constraint: IndexType) { // We consider a source type reverse mappable if it has a string index signature or if // it has one or more properties and is of a partially inferable type. - if (!(getIndexInfoOfType(source, IndexKind.String) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) { + if (!(getIndexInfoOfType(source, stringType) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) { return undefined; } // For arrays and tuples we infer new arrays and tuples where the reverse mapping has been @@ -21563,7 +21500,7 @@ namespace ts { // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol); - const stringIndexType = getIndexTypeOfType(source, IndexKind.String); + const stringIndexType = getIndexTypeOfType(source, stringType); const numberIndexInfo = getNonEnumNumberIndexInfo(source); const numberIndexType = numberIndexInfo && numberIndexInfo.type; inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target)); @@ -21729,18 +21666,18 @@ namespace ts { function inferFromIndexTypes(source: Type, target: Type) { // Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0; - const targetStringIndexType = getIndexTypeOfType(target, IndexKind.String); + const targetStringIndexType = getIndexTypeOfType(target, stringType); if (targetStringIndexType) { - const sourceIndexType = getIndexTypeOfType(source, IndexKind.String) || + const sourceIndexType = getIndexTypeOfType(source, stringType) || getImplicitIndexTypeOfType(source, IndexKind.String); if (sourceIndexType) { inferWithPriority(sourceIndexType, targetStringIndexType, priority); } } - const targetNumberIndexType = getIndexTypeOfType(target, IndexKind.Number); + const targetNumberIndexType = getIndexTypeOfType(target, numberType); if (targetNumberIndexType) { - const sourceIndexType = getIndexTypeOfType(source, IndexKind.Number) || - getIndexTypeOfType(source, IndexKind.String) || + const sourceIndexType = getIndexTypeOfType(source, numberType) || + getIndexTypeOfType(source, stringType) || getImplicitIndexTypeOfType(source, IndexKind.Number); if (sourceIndexType) { inferWithPriority(sourceIndexType, targetNumberIndexType, priority); @@ -22320,8 +22257,8 @@ namespace ts { if (!isTypeUsableAsPropertyName(nameType)) return errorType; const text = getPropertyNameFromType(nameType); return getTypeOfPropertyOfType(type, text) || - isNumericLiteralName(text) && includeUndefinedInIndexSignature(getIndexTypeOfType(type, IndexKind.Number)) || - includeUndefinedInIndexSignature(getIndexTypeOfType(type, IndexKind.String)) || + isNumericLiteralName(text) && includeUndefinedInIndexSignature(getIndexTypeOfType(type, numberType)) || + includeUndefinedInIndexSignature(getIndexTypeOfType(type, stringType)) || errorType; } @@ -23502,7 +23439,7 @@ namespace ts { } function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) { - if (getIndexInfoOfType(type, IndexKind.String)) { + if (getIndexInfoOfType(type, stringType)) { return true; } const prop = getPropertyOfType(type, propName); @@ -25361,15 +25298,15 @@ namespace ts { return restType; } } - return isNumericLiteralName(name) && getIndexTypeOfContextualType(t, IndexKind.Number) || - getIndexTypeOfContextualType(t, IndexKind.String); + return isNumericLiteralName(name) && getIndexTypeOfContextualType(t, numberType) || + getIndexTypeOfContextualType(t, stringType); } return undefined; }, /*noReductions*/ true); } - function getIndexTypeOfContextualType(type: Type, kind: IndexKind) { - return mapType(type, t => getIndexTypeOfStructuredType(t, kind), /*noReductions*/ true); + function getIndexTypeOfContextualType(type: Type, keyType: Type) { + return mapType(type, t => getIndexInfoOfStructuredType(t, keyType)?.type, /*noReductions*/ true); } // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of @@ -25402,8 +25339,8 @@ namespace ts { return propertyType; } } - return isNumericName(element.name!) && getIndexTypeOfContextualType(type, IndexKind.Number) || - getIndexTypeOfContextualType(type, IndexKind.String); + return isNumericName(element.name!) && getIndexTypeOfContextualType(type, numberType) || + getIndexTypeOfContextualType(type, stringType); } return undefined; } @@ -26042,7 +25979,7 @@ namespace ts { // get the contextual element type from it. So we do something similar to // getContextualTypeForElementExpression, which will crucially not error // if there is no index type / iterated type. - const restElementType = getIndexTypeOfType(spreadType, IndexKind.Number) || + const restElementType = getIndexTypeOfType(spreadType, numberType) || getIteratedTypeOrElementType(IterationUse.Destructuring, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false) || unknownType; elementTypes.push(restElementType); @@ -26167,15 +26104,15 @@ namespace ts { return isNumericLiteralName(symbol.escapedName) || (firstDecl && isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name)); } - function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], kind: IndexKind): IndexInfo { + function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], keyType: Type): IndexInfo { const propTypes: Type[] = []; for (let i = offset; i < properties.length; i++) { - if (kind === IndexKind.String || isSymbolWithNumericName(properties[i])) { + if (keyType === stringType || isSymbolWithNumericName(properties[i])) { propTypes.push(getTypeOfSymbol(properties[i])); } } const unionType = propTypes.length ? getUnionType(propTypes, UnionReduction.Subtype) : undefinedType; - return createIndexInfo(unionType, isConstContext(node)); + return createIndexInfo(keyType, unionType, isConstContext(node)); } function getImmediateAliasedSymbol(symbol: Symbol): Symbol | undefined { @@ -26273,7 +26210,7 @@ namespace ts { prop.flags |= impliedProp.flags & SymbolFlags.Optional; } - else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType!, IndexKind.String)) { + else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType!, stringType)) { error(memberDecl.name, Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType!)); } @@ -26383,9 +26320,9 @@ namespace ts { return createObjectLiteralType(); function createObjectLiteralType() { - const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.String) : undefined; - const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, IndexKind.Number) : undefined; - const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); + const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType) : undefined; + const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType) : undefined; + const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, createIndexInfoArray(stringIndexInfo, numberIndexInfo)); result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; if (isJSObjectLiteral) { result.objectFlags |= ObjectFlags.JSLiteral; @@ -26571,7 +26508,7 @@ namespace ts { childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol; const childPropMap = createSymbolTable(); childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol); - spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), + spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, emptyArray), attributes.symbol, objectFlags, /*readonly*/ false); } @@ -26592,7 +26529,7 @@ namespace ts { */ function createJsxAttributesType() { objectFlags |= freshObjectLiteralFlag; - const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, emptyArray); result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; return result; } @@ -26665,7 +26602,7 @@ namespace ts { } // Intrinsic string indexer case - const indexSignatureType = getIndexTypeOfType(intrinsicElementsType, IndexKind.String); + const indexSignatureType = getIndexTypeOfType(intrinsicElementsType, stringType); if (indexSignatureType) { links.jsxFlags |= JsxFlags.IntrinsicIndexedElement; return links.resolvedSymbol = intrinsicElementsType.symbol; @@ -26835,7 +26772,7 @@ namespace ts { if (intrinsicProp) { return getTypeOfSymbol(intrinsicProp); } - const indexSignatureType = getIndexTypeOfType(intrinsicElementsType, IndexKind.String); + const indexSignatureType = getIndexTypeOfType(intrinsicElementsType, stringType); if (indexSignatureType) { return indexSignatureType; } @@ -26890,7 +26827,7 @@ namespace ts { } else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) { return links.resolvedJsxElementAttributesType = - getIndexTypeOfType(getJsxType(JsxNames.IntrinsicElements, node), IndexKind.String) || errorType; + getIndexTypeOfType(getJsxType(JsxNames.IntrinsicElements, node), stringType) || errorType; } else { return links.resolvedJsxElementAttributesType = errorType; @@ -26994,9 +26931,8 @@ namespace ts { */ function isKnownProperty(targetType: Type, name: __String, isComparingJsxAttributes: boolean): boolean { if (targetType.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(targetType as ObjectType); - if (resolved.stringIndexInfo || - resolved.numberIndexInfo && isNumericLiteralName(name) || + if (getIndexInfoOfStructuredType(targetType, stringType) || + getIndexInfoOfStructuredType(targetType, numberType) && isNumericLiteralName(name) || getPropertyOfObjectType(targetType, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. @@ -27429,7 +27365,7 @@ namespace ts { let propType: Type; if (!prop) { - const indexInfo = !isPrivateIdentifier(right) && (assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined; + const indexInfo = !isPrivateIdentifier(right) && (assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? getIndexInfoOfType(apparentType, stringType) : undefined; if (!(indexInfo && indexInfo.type)) { if (isJSLiteralType(leftType)) { return anyType; @@ -27611,7 +27547,7 @@ namespace ts { let relatedInfo: Diagnostic | undefined; if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { for (const subtype of (containingType as UnionType).types) { - if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, IndexKind.String)) { + if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, stringType)) { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(subtype)); break; } @@ -27903,7 +27839,7 @@ namespace ts { * Return true if the given type is considered to have numeric property names. */ function hasNumericPropertyNames(type: Type) { - return getIndexTypeOfType(type, IndexKind.Number) && !getIndexTypeOfType(type, IndexKind.String); + return getIndexTypeOfType(type, numberType) && !getIndexTypeOfType(type, stringType); } /** @@ -28159,7 +28095,7 @@ namespace ts { function getSingleSignature(type: Type, kind: SignatureKind, allowMembers: boolean): Signature | undefined { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type as ObjectType); - if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { + if (allowMembers || resolved.properties.length === 0 && resolved.indexInfos.length === 0) { if (kind === SignatureKind.Call && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) { return resolved.callSignatures[0]; } @@ -30018,7 +29954,7 @@ namespace ts { if (isInJSFile(node)) { const jsSymbol = getSymbolOfExpando(node, /*allowDeclaration*/ false); if (jsSymbol?.exports?.size) { - const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, undefined, undefined); + const jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, emptyArray); jsAssignmentType.objectFlags |= ObjectFlags.JSLiteral; return getIntersectionType([returnType, jsAssignmentType]); } @@ -30121,7 +30057,7 @@ namespace ts { newSymbol.target = resolveSymbol(symbol); memberTable.set(InternalSymbolName.Default, newSymbol); const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); - const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + const defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, emptyArray, emptyArray, emptyArray); anonymousSymbol.type = defaultContainingObject; synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject; } @@ -30969,7 +30905,7 @@ namespace ts { } const returnType = getReturnTypeFromBody(node, checkMode); const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None); - const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined); + const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, emptyArray); returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType; return links.contextFreeType = returnOnlyType; } @@ -33715,7 +33651,7 @@ namespace ts { // Check if we're indexing with a numeric type and if either object or index types // is a generic type with a constraint that has a numeric index signature. const apparentObjectType = getApparentType(objectType); - if (getIndexInfoOfType(apparentObjectType, IndexKind.Number) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { + if (getIndexInfoOfType(apparentObjectType, numberType) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) { return type; } if (isGenericObjectType(objectType)) { @@ -36040,7 +35976,7 @@ namespace ts { return hasStringConstituent ? possibleOutOfBounds ? includeUndefinedInIndexSignature(stringType) : stringType : undefined; } - const arrayElementType = getIndexTypeOfType(arrayType, IndexKind.Number); + const arrayElementType = getIndexTypeOfType(arrayType, numberType); if (hasStringConstituent && arrayElementType) { // This is just an optimization for the case where arrayOrStringType is string | string[] if (arrayElementType.flags & TypeFlags.StringLike && !compilerOptions.noUncheckedIndexedAccess) { @@ -36881,18 +36817,21 @@ namespace ts { } function checkIndexConstraints(type: Type, isStatic?: boolean) { - const declaredNumberIndexer = getIndexDeclarationOfSymbolTable(isStatic ? type.symbol?.exports : type.symbol?.members, IndexKind.Number); - const declaredStringIndexer = getIndexDeclarationOfSymbolTable(isStatic ? type.symbol?.exports : type.symbol?.members, IndexKind.String); + const symbolTable = isStatic ? type.symbol?.exports : type.symbol?.members; + const indexSymbol = symbolTable && getIndexSymbolFromSymbolTable(symbolTable); + const indexInfos = indexSymbol ? getIndexInfosOfIndexSymbol(indexSymbol) : emptyArray; + const declaredStringIndexer = findIndexInfo(indexInfos, stringType)?.declaration; + const declaredNumberIndexer = findIndexInfo(indexInfos, numberType)?.declaration; - const stringIndexType = getIndexTypeOfType(type, IndexKind.String); - const numberIndexType = getIndexTypeOfType(type, IndexKind.Number); + const stringIndexType = getIndexTypeOfType(type, stringType); + const numberIndexType = getIndexTypeOfType(type, numberType); if (stringIndexType || numberIndexType) { forEach(getPropertiesOfObjectType(type), prop => { if (isStatic && prop.flags & SymbolFlags.Prototype) return; const propType = getTypeOfSymbol(prop); - checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); - checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); + checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, stringType); + checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, numberType); }); const classDeclaration = type.symbol.valueDeclaration; @@ -36904,8 +36843,8 @@ namespace ts { if (!hasSyntacticModifier(member, ModifierFlags.Static) && !hasBindableName(member)) { const symbol = getSymbolOfNode(member); const propType = getTypeOfSymbol(symbol); - checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String); - checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number); + checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, stringType); + checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, numberType); } } } @@ -36916,7 +36855,7 @@ namespace ts { errorNode = declaredNumberIndexer || declaredStringIndexer; // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer if (!errorNode && (getObjectFlags(type) & ObjectFlags.Interface)) { - const someBaseTypeHasBothIndexers = forEach(getBaseTypes(type as InterfaceType), base => getIndexTypeOfType(base, IndexKind.String) && getIndexTypeOfType(base, IndexKind.Number)); + const someBaseTypeHasBothIndexers = forEach(getBaseTypes(type as InterfaceType), base => getIndexTypeOfType(base, stringType) && getIndexTypeOfType(base, numberType)); errorNode = someBaseTypeHasBothIndexers || !type.symbol.declarations ? undefined : type.symbol.declarations[0]; } } @@ -36932,7 +36871,7 @@ namespace ts { containingType: Type, indexDeclaration: Declaration | undefined, indexType: Type | undefined, - indexKind: IndexKind): void { + keyType: Type): void { // ESSymbol properties apply to neither string nor numeric indexers. if (!indexType || isKnownSymbol(prop)) { @@ -36947,7 +36886,7 @@ namespace ts { } // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) { + if (keyType === numberType && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) { return; } @@ -36967,13 +36906,13 @@ namespace ts { // for interfaces property and indexer might be inherited from different bases // check if any base class already has both property and indexer. // check should be performed only if 'type' is the first type that brings property\indexer together - const someBaseClassHasBothPropertyAndIndexer = forEach(getBaseTypes(containingType as InterfaceType), base => getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind)); + const someBaseClassHasBothPropertyAndIndexer = forEach(getBaseTypes(containingType as InterfaceType), base => getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, keyType)); errorNode = someBaseClassHasBothPropertyAndIndexer || !containingType.symbol.declarations ? undefined : containingType.symbol.declarations[0]; } if (errorNode && !isTypeAssignableTo(propertyType, indexType)) { const errorMessage = - indexKind === IndexKind.String + keyType === stringType ? Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2 : Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2; error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType)); @@ -40616,7 +40555,7 @@ namespace ts { autoArrayType = createArrayType(autoType); if (autoArrayType === emptyObjectType) { // autoArrayType is used as a marker, so even if global Array type is not defined, it needs to be a unique type - autoArrayType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + autoArrayType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); } globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray" as __String, /*arity*/ 1) as GenericType || globalArrayType; diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index b03ef31db6e11..4cf93b42e7f5a 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -8,7 +8,6 @@ namespace ts { resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType, getTypeOfSymbol: (sym: Symbol) => Type, getResolvedSymbol: (node: Node) => Symbol, - getIndexTypeOfStructuredType: (type: Type, kind: IndexKind) => Type | undefined, getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined, getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier, getTypeArguments: (type: TypeReference) => readonly Type[]) { @@ -140,13 +139,10 @@ namespace ts { } function visitObjectType(type: ObjectType): void { - const stringIndexType = getIndexTypeOfStructuredType(type, IndexKind.String); - visitType(stringIndexType); - const numberIndexType = getIndexTypeOfStructuredType(type, IndexKind.Number); - visitType(numberIndexType); - - // The two checks above *should* have already resolved the type (if needed), so this should be cached const resolved = resolveStructuredTypeMembers(type); + for (const info of resolved.indexInfos) { + visitType(info.type); + } for (const signature of resolved.callSignatures) { visitSignature(signature); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1509db1d56927..301a7ef0f61c2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4114,8 +4114,8 @@ namespace ts { signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): SignatureDeclaration & {typeArguments?: NodeArray} | undefined; /* @internal */ signatureToSignatureDeclaration(signature: Signature, kind: SyntaxKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): SignatureDeclaration & {typeArguments?: NodeArray} | undefined; // eslint-disable-line @typescript-eslint/unified-signatures /** Note that the resulting nodes cannot be checked. */ - indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; - /* @internal */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): IndexSignatureDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; + /* @internal */ indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker?: SymbolTracker): IndexSignatureDeclaration | undefined; // eslint-disable-line @typescript-eslint/unified-signatures /** Note that the resulting nodes cannot be checked. */ symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined; /** Note that the resulting nodes cannot be checked. */ @@ -4240,7 +4240,7 @@ namespace ts { /* @internal */ createPromiseType(type: Type): Type; /* @internal */ isTypeAssignableTo(source: Type, target: Type): boolean; - /* @internal */ createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): Type; + /* @internal */ createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], indexInfos: IndexInfo[]): Type; /* @internal */ createSignature( declaration: SignatureDeclaration | undefined, typeParameters: readonly TypeParameter[] | undefined, @@ -4252,7 +4252,7 @@ namespace ts { flags: SignatureFlags ): Signature; /* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol; - /* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo; + /* @internal */ createIndexInfo(keyType: Type, type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo; /* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult; /* @internal */ tryFindAmbientModule(moduleName: string): Symbol | undefined; /* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol | undefined; @@ -5267,8 +5267,7 @@ namespace ts { /* @internal */ properties?: Symbol[]; // Properties /* @internal */ callSignatures?: readonly Signature[]; // Call signatures of type /* @internal */ constructSignatures?: readonly Signature[]; // Construct signatures of type - /* @internal */ stringIndexInfo?: IndexInfo; // String indexing info - /* @internal */ numberIndexInfo?: IndexInfo; // Numeric indexing info + /* @internal */ indexInfos?: readonly IndexInfo[]; // Index signatures /* @internal */ objectTypeWithoutAbstractConstructSignatures?: ObjectType; } @@ -5293,8 +5292,7 @@ namespace ts { declaredProperties: Symbol[]; // Declared members declaredCallSignatures: Signature[]; // Declared call signatures declaredConstructSignatures: Signature[]; // Declared construct signatures - declaredStringIndexInfo?: IndexInfo; // Declared string indexing info - declaredNumberIndexInfo?: IndexInfo; // Declared numeric indexing info + declaredIndexInfos: IndexInfo[]; // Declared index signatures } /** @@ -5452,6 +5450,7 @@ namespace ts { properties: Symbol[]; // Properties callSignatures: readonly Signature[]; // Call signatures of type constructSignatures: readonly Signature[]; // Construct signatures of type + indexInfos: readonly IndexInfo[]; // Index signatures } /* @internal */ @@ -5688,6 +5687,7 @@ namespace ts { } export interface IndexInfo { + keyType: Type; type: Type; isReadonly: boolean; declaration?: IndexSignatureDeclaration; diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 01410672b3f28..e1f17cb2856fc 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -70,7 +70,7 @@ namespace ts.codefix { function createMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind): void { const indexInfoOfKind = checker.getIndexInfoOfType(type, kind); if (indexInfoOfKind) { - insertInterfaceMemberNode(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context))!); + insertInterfaceMemberNode(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, classDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context))!); } } diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 15f64a271cd6c..94456fec7b172 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -955,13 +955,15 @@ namespace ts.codefix { } calls.push(...checker.getSignaturesOfType(anon, SignatureKind.Call)); constructs.push(...checker.getSignaturesOfType(anon, SignatureKind.Construct)); - if (anon.stringIndexInfo) { - stringIndices.push(anon.stringIndexInfo.type); - stringIndexReadonly = stringIndexReadonly || anon.stringIndexInfo.isReadonly; + const stringIndexInfo = checker.getIndexInfoOfType(anon, IndexKind.String); + if (stringIndexInfo) { + stringIndices.push(stringIndexInfo.type); + stringIndexReadonly = stringIndexReadonly || stringIndexInfo.isReadonly; } - if (anon.numberIndexInfo) { - numberIndices.push(anon.numberIndexInfo.type); - numberIndexReadonly = numberIndexReadonly || anon.numberIndexInfo.isReadonly; + const numberIndexInfo = checker.getIndexInfoOfType(anon, IndexKind.Number); + if (numberIndexInfo) { + numberIndices.push(numberIndexInfo.type); + numberIndexReadonly = numberIndexReadonly || numberIndexInfo.isReadonly; } } const members = mapEntries(props, (name, types) => { @@ -970,13 +972,15 @@ namespace ts.codefix { s.type = checker.getUnionType(types); return [name, s]; }); + const indexInfos = []; + if (stringIndices.length) indexInfos.push(checker.createIndexInfo(checker.getStringType(), checker.getUnionType(stringIndices), stringIndexReadonly)); + if (numberIndices.length) indexInfos.push(checker.createIndexInfo(checker.getNumberType(), checker.getUnionType(numberIndices), numberIndexReadonly)); return checker.createAnonymousType( anons[0].symbol, members as UnderscoreEscapedMap, calls, constructs, - stringIndices.length ? checker.createIndexInfo(checker.getUnionType(stringIndices), stringIndexReadonly) : undefined, - numberIndices.length ? checker.createIndexInfo(checker.getUnionType(numberIndices), numberIndexReadonly) : undefined); + indexInfos); } function inferTypes(usage: Usage): Type[] { @@ -1015,8 +1019,8 @@ namespace ts.codefix { } const callSignatures: Signature[] = usage.calls ? [getSignatureFromCalls(usage.calls)] : []; const constructSignatures: Signature[] = usage.constructs ? [getSignatureFromCalls(usage.constructs)] : []; - const stringIndexInfo = usage.stringIndex && checker.createIndexInfo(combineFromUsage(usage.stringIndex), /*isReadonly*/ false); - return checker.createAnonymousType(/*symbol*/ undefined, members, callSignatures, constructSignatures, stringIndexInfo, /*numberIndexInfo*/ undefined); + const indexInfos = usage.stringIndex ? [checker.createIndexInfo(checker.getStringType(), combineFromUsage(usage.stringIndex), /*isReadonly*/ false)] : []; + return checker.createAnonymousType(/*symbol*/ undefined, members, callSignatures, constructSignatures, indexInfos); } function inferNamedTypesFromProperties(usage: Usage): Type[] { @@ -1121,7 +1125,7 @@ namespace ts.codefix { } function getFunctionFromCalls(calls: CallUsage[]) { - return checker.createAnonymousType(/*symbol*/ undefined, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + return checker.createAnonymousType(/*symbol*/ undefined, createSymbolTable(), [getSignatureFromCalls(calls)], emptyArray, emptyArray); } function getSignatureFromCalls(calls: CallUsage[]): Signature { diff --git a/src/services/codefixes/returnValueCorrect.ts b/src/services/codefixes/returnValueCorrect.ts index afe5e0c760652..c7631607e1feb 100644 --- a/src/services/codefixes/returnValueCorrect.ts +++ b/src/services/codefixes/returnValueCorrect.ts @@ -76,7 +76,7 @@ namespace ts.codefix { const member = checker.createSymbol(SymbolFlags.Property, label.escapedText); member.type = checker.getTypeAtLocation(expression); const members = createSymbolTable([member]); - return checker.createAnonymousType(/*symbol*/ undefined, members, [], [], /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); + return checker.createAnonymousType(/*symbol*/ undefined, members, [], [], []); } function getFixInfo(checker: TypeChecker, declaration: FunctionLikeDeclaration, expectType: Type, isFunctionType: boolean): Info | undefined { @@ -152,8 +152,7 @@ namespace ts.codefix { createSymbolTable(), [newSig], [], - /*stringIndexInfo*/ undefined, - /*numberIndexInfo*/ undefined); + []); } else { exprType = checker.getAnyType(); From fc107dcfa35f17388de2502e6cb704fed7861f40 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 31 May 2021 12:29:04 -0700 Subject: [PATCH 02/56] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 6 +++--- tests/baselines/reference/api/typescript.d.ts | 6 +++--- .../declFileTypeAnnotationTypeLiteral.types | 2 +- ...TypeAnnotationVisibilityErrorTypeLiteral.js | 2 +- ...eAnnotationVisibilityErrorTypeLiteral.types | 6 +++--- .../reference/parserES5SymbolIndexer3.types | 2 +- .../reference/parserSymbolIndexer4.types | 2 +- .../reference/readonlyMembers.errors.txt | 4 ++-- .../baselines/reference/readonlyMembers.types | 6 +++--- .../reference/recursiveTypesWithTypeof.types | 18 +++++++++--------- 10 files changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index dcbd016c31e3b..efa2864c2ee67 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2208,7 +2208,7 @@ declare namespace ts { typeArguments?: NodeArray; } | undefined; /** Note that the resulting nodes cannot be checked. */ - indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; /** Note that the resulting nodes cannot be checked. */ symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined; /** Note that the resulting nodes cannot be checked. */ @@ -2606,8 +2606,7 @@ declare namespace ts { declaredProperties: Symbol[]; declaredCallSignatures: Signature[]; declaredConstructSignatures: Signature[]; - declaredStringIndexInfo?: IndexInfo; - declaredNumberIndexInfo?: IndexInfo; + declaredIndexInfos: IndexInfo[]; } /** * Type references (ObjectFlags.Reference). When a class or interface has type parameters or @@ -2721,6 +2720,7 @@ declare namespace ts { Number = 1 } export interface IndexInfo { + keyType: Type; type: Type; isReadonly: boolean; declaration?: IndexSignatureDeclaration; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a3d17250a215c..e85d77b4d9c77 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2208,7 +2208,7 @@ declare namespace ts { typeArguments?: NodeArray; } | undefined; /** Note that the resulting nodes cannot be checked. */ - indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; + indexInfoToIndexSignatureDeclaration(indexInfo: IndexInfo, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): IndexSignatureDeclaration | undefined; /** Note that the resulting nodes cannot be checked. */ symbolToEntityName(symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): EntityName | undefined; /** Note that the resulting nodes cannot be checked. */ @@ -2606,8 +2606,7 @@ declare namespace ts { declaredProperties: Symbol[]; declaredCallSignatures: Signature[]; declaredConstructSignatures: Signature[]; - declaredStringIndexInfo?: IndexInfo; - declaredNumberIndexInfo?: IndexInfo; + declaredIndexInfos: IndexInfo[]; } /** * Type references (ObjectFlags.Reference). When a class or interface has type parameters or @@ -2721,6 +2720,7 @@ declare namespace ts { Number = 1 } export interface IndexInfo { + keyType: Type; type: Type; isReadonly: boolean; declaration?: IndexSignatureDeclaration; diff --git a/tests/baselines/reference/declFileTypeAnnotationTypeLiteral.types b/tests/baselines/reference/declFileTypeAnnotationTypeLiteral.types index 30d386b6c17d2..72dbb5251d20f 100644 --- a/tests/baselines/reference/declFileTypeAnnotationTypeLiteral.types +++ b/tests/baselines/reference/declFileTypeAnnotationTypeLiteral.types @@ -15,7 +15,7 @@ module m { // Object literal with everything var x: { ->x : { (a: number): c; (a: string): g; new (a: number): c; new (a: string): m.c; [n: string]: c; [n: number]: c; a: c; b: g; m1(): g; m2(a: string, b?: number, ...c: c[]): string; } +>x : { (a: number): c; (a: string): g; new (a: number): c; new (a: string): m.c; [n: number]: c; [n: string]: c; a: c; b: g; m1(): g; m2(a: string, b?: number, ...c: c[]): string; } // Call signatures (a: number): c; diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.js b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.js index b3ba6a4ee5222..f7b2e37de6c40 100644 --- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.js +++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.js @@ -86,8 +86,8 @@ declare module m { }; export var x3: { (): m2.public1[]; - [s: string]: m2.public1; [n: number]: private1; + [s: string]: m2.public1; x: private1; y: m2.public1; method(): private1; diff --git a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.types b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.types index 7acd7e779f072..e5be6e753fe70 100644 --- a/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.types +++ b/tests/baselines/reference/declFileTypeAnnotationVisibilityErrorTypeLiteral.types @@ -14,7 +14,7 @@ module m { } export var x: { ->x : { (): m2.public1[]; [s: string]: m2.public1; [n: number]: private1; x: private1; y: m2.public1; method(): private1; } +>x : { (): m2.public1[]; [n: number]: private1; [s: string]: m2.public1; x: private1; y: m2.public1; method(): private1; } x: private1; >x : private1 @@ -62,8 +62,8 @@ module m { } }; export var x3 = x; ->x3 : { (): m2.public1[]; [s: string]: m2.public1; [n: number]: private1; x: private1; y: m2.public1; method(): private1; } ->x : { (): m2.public1[]; [s: string]: m2.public1; [n: number]: private1; x: private1; y: m2.public1; method(): private1; } +>x3 : { (): m2.public1[]; [n: number]: private1; [s: string]: m2.public1; x: private1; y: m2.public1; method(): private1; } +>x : { (): m2.public1[]; [n: number]: private1; [s: string]: m2.public1; x: private1; y: m2.public1; method(): private1; } // Function type export var y: (a: private1) => m2.public1; diff --git a/tests/baselines/reference/parserES5SymbolIndexer3.types b/tests/baselines/reference/parserES5SymbolIndexer3.types index 3476226e2b77a..a39d1e8f61f71 100644 --- a/tests/baselines/reference/parserES5SymbolIndexer3.types +++ b/tests/baselines/reference/parserES5SymbolIndexer3.types @@ -1,6 +1,6 @@ === tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer3.ts === var x: { ->x : {} +>x : { [s: symbol]: string; } [s: symbol]: string; >s : symbol diff --git a/tests/baselines/reference/parserSymbolIndexer4.types b/tests/baselines/reference/parserSymbolIndexer4.types index 7509072a12cd2..0745c2c223efc 100644 --- a/tests/baselines/reference/parserSymbolIndexer4.types +++ b/tests/baselines/reference/parserSymbolIndexer4.types @@ -1,6 +1,6 @@ === tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer4.ts === var x: { ->x : {} +>x : { [s: symbol]: string; } [s: symbol]: string; >s : symbol diff --git a/tests/baselines/reference/readonlyMembers.errors.txt b/tests/baselines/reference/readonlyMembers.errors.txt index bea7932ed4cd7..70f7384318486 100644 --- a/tests/baselines/reference/readonlyMembers.errors.txt +++ b/tests/baselines/reference/readonlyMembers.errors.txt @@ -12,7 +12,7 @@ tests/cases/compiler/readonlyMembers.ts(39,3): error TS2540: Cannot assign to 'a tests/cases/compiler/readonlyMembers.ts(48,3): error TS2540: Cannot assign to 'A' because it is a read-only property. tests/cases/compiler/readonlyMembers.ts(55,3): error TS2540: Cannot assign to 'a' because it is a read-only property. tests/cases/compiler/readonlyMembers.ts(61,1): error TS2542: Index signature in type '{ readonly [x: string]: string; }' only permits reading. -tests/cases/compiler/readonlyMembers.ts(64,1): error TS2542: Index signature in type '{ [x: string]: string; readonly [x: number]: string; }' only permits reading. +tests/cases/compiler/readonlyMembers.ts(64,1): error TS2542: Index signature in type '{ readonly [x: number]: string; [x: string]: string; }' only permits reading. ==== tests/cases/compiler/readonlyMembers.ts (15 errors) ==== @@ -109,5 +109,5 @@ tests/cases/compiler/readonlyMembers.ts(64,1): error TS2542: Index signature in let yy: { readonly [x: number]: string, [x: string]: string }; yy[1] = "abc"; // Error ~~~~~ -!!! error TS2542: Index signature in type '{ [x: string]: string; readonly [x: number]: string; }' only permits reading. +!!! error TS2542: Index signature in type '{ readonly [x: number]: string; [x: string]: string; }' only permits reading. yy["foo"] = "abc"; \ No newline at end of file diff --git a/tests/baselines/reference/readonlyMembers.types b/tests/baselines/reference/readonlyMembers.types index 4a69289b710b2..eb71ec9eb59aa 100644 --- a/tests/baselines/reference/readonlyMembers.types +++ b/tests/baselines/reference/readonlyMembers.types @@ -258,21 +258,21 @@ xx["foo"] = "abc"; // Error >"abc" : "abc" let yy: { readonly [x: number]: string, [x: string]: string }; ->yy : { [x: string]: string; readonly [x: number]: string; } +>yy : { readonly [x: number]: string; [x: string]: string; } >x : number >x : string yy[1] = "abc"; // Error >yy[1] = "abc" : "abc" >yy[1] : string ->yy : { [x: string]: string; readonly [x: number]: string; } +>yy : { readonly [x: number]: string; [x: string]: string; } >1 : 1 >"abc" : "abc" yy["foo"] = "abc"; >yy["foo"] = "abc" : "abc" >yy["foo"] : string ->yy : { [x: string]: string; readonly [x: number]: string; } +>yy : { readonly [x: number]: string; [x: string]: string; } >"foo" : "foo" >"abc" : "abc" diff --git a/tests/baselines/reference/recursiveTypesWithTypeof.types b/tests/baselines/reference/recursiveTypesWithTypeof.types index ff80ad048b199..64a0ea35b5466 100644 --- a/tests/baselines/reference/recursiveTypesWithTypeof.types +++ b/tests/baselines/reference/recursiveTypesWithTypeof.types @@ -123,22 +123,22 @@ var j2 = new j2(j2); // Indexers var k: { [n: number]: typeof k;[s: string]: typeof k }; ->k : { [s: string]: any; [n: number]: any; } +>k : { [n: number]: any; [s: string]: any; } >n : number ->k : { [s: string]: any; [n: number]: any; } +>k : { [n: number]: any; [s: string]: any; } >s : string ->k : { [s: string]: any; [n: number]: any; } +>k : { [n: number]: any; [s: string]: any; } var k = k[0]; ->k : { [s: string]: any; [n: number]: any; } ->k[0] : { [s: string]: any; [n: number]: any; } ->k : { [s: string]: any; [n: number]: any; } +>k : { [n: number]: any; [s: string]: any; } +>k[0] : { [n: number]: any; [s: string]: any; } +>k : { [n: number]: any; [s: string]: any; } >0 : 0 var k = k['']; ->k : { [s: string]: any; [n: number]: any; } ->k[''] : { [s: string]: any; [n: number]: any; } ->k : { [s: string]: any; [n: number]: any; } +>k : { [n: number]: any; [s: string]: any; } +>k[''] : { [n: number]: any; [s: string]: any; } +>k : { [n: number]: any; [s: string]: any; } >'' : "" // Hybrid - contains type literals as well as type arguments From 60cff4422940f851ff7879b1c9528527037eb36d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 31 May 2021 12:32:43 -0700 Subject: [PATCH 03/56] Remove another usage of IndexKind enum --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5c878e5d89d90..653ae34a6816a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11999,16 +11999,16 @@ namespace ts { return info1 ? info2 ? [info1, info2] : [info1] : info2 ? [info2] : emptyArray; } - function getImplicitIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined { + function getImplicitIndexTypeOfType(type: Type, keyType: Type): Type | undefined { if (isObjectTypeWithInferableIndex(type)) { const propTypes: Type[] = []; for (const prop of getPropertiesOfType(type)) { - if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) { + if (keyType === stringType || isNumericLiteralName(prop.escapedName)) { const propType = getTypeOfSymbol(prop); propTypes.push(prop.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType); } } - if (kind === IndexKind.String) { + if (keyType === stringType) { append(propTypes, getIndexTypeOfType(type, numberType)); } if (propTypes.length) { @@ -21669,7 +21669,7 @@ namespace ts { const targetStringIndexType = getIndexTypeOfType(target, stringType); if (targetStringIndexType) { const sourceIndexType = getIndexTypeOfType(source, stringType) || - getImplicitIndexTypeOfType(source, IndexKind.String); + getImplicitIndexTypeOfType(source, stringType); if (sourceIndexType) { inferWithPriority(sourceIndexType, targetStringIndexType, priority); } @@ -21678,7 +21678,7 @@ namespace ts { if (targetNumberIndexType) { const sourceIndexType = getIndexTypeOfType(source, numberType) || getIndexTypeOfType(source, stringType) || - getImplicitIndexTypeOfType(source, IndexKind.Number); + getImplicitIndexTypeOfType(source, numberType); if (sourceIndexType) { inferWithPriority(sourceIndexType, targetNumberIndexType, priority); } From 9900302261a50f815549fa23a6577df4fb052db8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 1 Jun 2021 07:31:56 -0700 Subject: [PATCH 04/56] Update getIndexedAccessType and resolveMappedTypeMembers --- src/compiler/checker.ts | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 653ae34a6816a..3922e87a1a13b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10840,7 +10840,7 @@ namespace ts { constructSignatures = appendSignatures(constructSignatures, signatures); } callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); - indexInfos = reduceLeft(getIndexInfosOfType(t), appendIndexInfo, indexInfos); + indexInfos = reduceLeft(getIndexInfosOfType(t), (infos, newInfo) => appendIndexInfo(infos, newInfo, /*union*/ false), indexInfos); } setStructuredTypeMembers(type, emptySymbols, callSignatures || emptyArray, constructSignatures || emptyArray, indexInfos || emptyArray); } @@ -10854,12 +10854,14 @@ namespace ts { return signatures; } - function appendIndexInfo(indexInfos: IndexInfo[] | undefined, newInfo: IndexInfo) { + function appendIndexInfo(indexInfos: IndexInfo[] | undefined, newInfo: IndexInfo, union: boolean) { if (indexInfos) { for (let i = 0; i < indexInfos.length; i++) { const info = indexInfos[i]; if (info.keyType === newInfo.keyType) { - indexInfos[i] = createIndexInfo(info.keyType, getIntersectionType([info.type, newInfo.type]), info.isReadonly && newInfo.isReadonly); + indexInfos[i] = createIndexInfo(info.keyType, + union ? getUnionType([info.type, newInfo.type]) : getIntersectionType([info.type, newInfo.type]), + union ? info.isReadonly || newInfo.isReadonly : info.isReadonly && newInfo.isReadonly); return indexInfos; } } @@ -11033,8 +11035,7 @@ namespace ts { /** Resolve the members of a mapped type { [P in K]: T } */ function resolveMappedTypeMembers(type: MappedType) { const members: SymbolTable = createSymbolTable(); - let stringIndexInfo: IndexInfo | undefined; - let numberIndexInfo: IndexInfo | undefined; + let indexInfos: IndexInfo[] | undefined; // Resolve upfront such that recursive references see an empty object type. setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type, @@ -11061,7 +11062,7 @@ namespace ts { else { forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, createIndexInfoArray(stringIndexInfo, numberIndexInfo)); + setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos || emptyArray); function addMemberForKeyType(keyType: Type) { const propNameType = nameType ? instantiateType(nameType, appendTypeMapping(type.mapper, typeParameter, keyType)) : keyType; @@ -11101,16 +11102,13 @@ namespace ts { members.set(propName, prop); } } - else if (propNameType.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum)) { + else if (propNameType.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum | TypeFlags.ESSymbol) || isPatternLiteralType(propNameType)) { + const indexKeyType = propNameType.flags & (TypeFlags.Any | TypeFlags.String) ? stringType : + propNameType.flags & (TypeFlags.Number | TypeFlags.Enum) ? numberType : + propNameType; const propType = instantiateType(templateType, appendTypeMapping(type.mapper, typeParameter, keyType)); - if (propNameType.flags & (TypeFlags.Any | TypeFlags.String)) { - stringIndexInfo = createIndexInfo(stringType, stringIndexInfo ? getUnionType([stringIndexInfo.type, propType]) : propType, - !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); - } - else { - numberIndexInfo = createIndexInfo(numberType, numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType, - !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); - } + const indexInfo = createIndexInfo(indexKeyType, propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); + indexInfos = appendIndexInfo(indexInfos, indexInfo, /*union*/ true); } } } @@ -12018,6 +12016,12 @@ namespace ts { return undefined; } + function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { + const indexInfos = getIndexInfosOfType(type); + return find(indexInfos, info => info.keyType !== stringType && isTypeAssignableTo(keyType, info.keyType)) || + findIndexInfo(indexInfos, stringType); + } + // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual // type checking functions). function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] | undefined { @@ -14634,16 +14638,15 @@ namespace ts { if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { return objectType; } - const stringIndexInfo = getIndexInfoOfType(objectType, stringType); - const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, numberType) || stringIndexInfo; + const indexInfo = getApplicableIndexInfo(objectType, indexType); if (indexInfo) { - if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo === stringIndexInfo) { + if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo.keyType === stringType) { if (accessExpression) { error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType)); } return undefined; } - if (accessNode && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { + if (accessNode && indexInfo.keyType === stringType && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { const indexNode = getIndexNodeForAccessExpression(accessNode); error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); return accessFlags & AccessFlags.IncludeUndefined ? getUnionType([indexInfo.type, undefinedType]) : indexInfo.type; From f27bea2b8a6b98223aa4b9fd697ea3ae71aace45 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 1 Jun 2021 07:32:25 -0700 Subject: [PATCH 05/56] Accept new baselines --- tests/baselines/reference/mappedTypeWithAny.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/mappedTypeWithAny.types b/tests/baselines/reference/mappedTypeWithAny.types index 6aa71ef174070..c95a17ab43b51 100644 --- a/tests/baselines/reference/mappedTypeWithAny.types +++ b/tests/baselines/reference/mappedTypeWithAny.types @@ -10,7 +10,7 @@ declare let x0: keyof any; >x0 : string | number | symbol declare let x1: { [P in any]: Item }; ->x1 : { [x: string]: Item; [x: number]: Item; } +>x1 : { [x: string]: Item; [x: number]: Item; [x: symbol]: Item; } declare let x2: { [P in string]: Item }; >x2 : { [x: string]: Item; } From a064ec157e77af6c7bebe0ca48163ca660291722 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 1 Jun 2021 17:49:20 -0700 Subject: [PATCH 06/56] Update grammar checking for index signatures --- src/compiler/checker.ts | 24 ++++++++---------------- src/compiler/diagnosticMessages.json | 16 ++++++++-------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3922e87a1a13b..7bd568990d041 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -41154,23 +41154,15 @@ namespace ts { if (!parameter.type) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } - if (parameter.type.kind !== SyntaxKind.StringKeyword && parameter.type.kind !== SyntaxKind.NumberKeyword) { - const type = getTypeFromTypeNode(parameter.type); - - if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { - return grammarErrorOnNode(parameter.name, - Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, - getTextOfNode(parameter.name), - typeToString(type), - typeToString(node.type ? getTypeFromTypeNode(node.type) : anyType)); - } - - if (type.flags & TypeFlags.Union && allTypesAssignableToKind(type, TypeFlags.StringOrNumberLiteral, /*strict*/ true)) { - return grammarErrorOnNode(parameter.name, - Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); + const type = getTypeFromTypeNode(parameter.type); + if (!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol | TypeFlags.TemplateLiteral))) { + if (type.flags & TypeFlags.Union && allTypesAssignableToKind(type, TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol, /*strict*/ true)) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); } - - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_either_string_or_number); + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type); + } + if (type.flags & TypeFlags.TemplateLiteral && !isPatternLiteralType(type)) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_generic_type); } if (!node.type) { return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_a_type_annotation); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c71967b2eaffe..dcc8eddb52c57 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -75,10 +75,6 @@ "category": "Error", "code": 1022 }, - "An index signature parameter type must be either 'string' or 'number'.": { - "category": "Error", - "code": 1023 - }, "'readonly' modifier can only appear on a property declaration or index signature.": { "category": "Error", "code": 1024 @@ -891,6 +887,14 @@ "category": "Error", "code": 1267 }, + "An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type.": { + "category": "Error", + "code": 1268 + }, + "An index signature parameter type cannot be a generic type.": { + "category": "Error", + "code": 1269 + }, "'with' statements are not allowed in an async function block.": { "category": "Error", @@ -996,10 +1000,6 @@ "category": "Error", "code": 1335 }, - "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead.": { - "category": "Error", - "code": 1336 - }, "An index signature parameter type cannot be a union type. Consider using a mapped object type instead.": { "category": "Error", "code": 1337 From 01cb82584b3bb605de4410a27490245597ee829d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 1 Jun 2021 17:49:33 -0700 Subject: [PATCH 07/56] Accept new baselines --- .../reference/arraySigChecking.errors.txt | 4 ++-- .../reference/bigintIndex.errors.txt | 4 ++-- ...eclarationEmitIndexTypeNotFound.errors.txt | 4 ++-- ...ndexTypeHasSensibleErrorMessage.errors.txt | 4 ++-- ...eReferenceWithoutTypeArgument.d.errors.txt | 4 ++-- ...ypeReferenceWithoutTypeArgument.errors.txt | 4 ++-- ...peReferenceWithoutTypeArgument2.errors.txt | 4 ++-- ...peReferenceWithoutTypeArgument3.errors.txt | 4 ++-- .../reference/indexTypeCheck.errors.txt | 4 ++-- .../reference/indexerConstraints2.errors.txt | 22 +++++++------------ .../parserES5SymbolIndexer1.errors.txt | 9 -------- .../parserES5SymbolIndexer2.errors.txt | 9 -------- .../parserES5SymbolIndexer3.errors.txt | 9 -------- .../parserIndexSignature6.errors.txt | 4 ++-- .../parserIndexSignature8.errors.txt | 8 +++---- .../reference/parserSymbolIndexer1.errors.txt | 9 -------- .../reference/parserSymbolIndexer2.errors.txt | 9 -------- .../reference/parserSymbolIndexer3.errors.txt | 9 -------- .../reference/parserSymbolIndexer4.errors.txt | 9 -------- .../reference/symbolProperty17.errors.txt | 14 ------------ .../reference/symbolProperty29.errors.txt | 12 ---------- .../reference/symbolProperty30.errors.txt | 12 ---------- .../reference/symbolProperty31.errors.txt | 14 ------------ .../reference/symbolProperty32.errors.txt | 14 ------------ .../reference/symbolProperty33.errors.txt | 5 +---- .../reference/symbolProperty34.errors.txt | 5 +---- 26 files changed, 34 insertions(+), 175 deletions(-) delete mode 100644 tests/baselines/reference/parserES5SymbolIndexer1.errors.txt delete mode 100644 tests/baselines/reference/parserES5SymbolIndexer2.errors.txt delete mode 100644 tests/baselines/reference/parserES5SymbolIndexer3.errors.txt delete mode 100644 tests/baselines/reference/parserSymbolIndexer1.errors.txt delete mode 100644 tests/baselines/reference/parserSymbolIndexer2.errors.txt delete mode 100644 tests/baselines/reference/parserSymbolIndexer3.errors.txt delete mode 100644 tests/baselines/reference/parserSymbolIndexer4.errors.txt delete mode 100644 tests/baselines/reference/symbolProperty17.errors.txt delete mode 100644 tests/baselines/reference/symbolProperty29.errors.txt delete mode 100644 tests/baselines/reference/symbolProperty30.errors.txt delete mode 100644 tests/baselines/reference/symbolProperty31.errors.txt delete mode 100644 tests/baselines/reference/symbolProperty32.errors.txt diff --git a/tests/baselines/reference/arraySigChecking.errors.txt b/tests/baselines/reference/arraySigChecking.errors.txt index 5bf4cfdd58e07..9d7ef5ef0634a 100644 --- a/tests/baselines/reference/arraySigChecking.errors.txt +++ b/tests/baselines/reference/arraySigChecking.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/arraySigChecking.ts(11,17): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/arraySigChecking.ts(11,17): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/arraySigChecking.ts(18,27): error TS2322: Type 'void' is not assignable to type 'string'. tests/cases/compiler/arraySigChecking.ts(22,13): error TS2322: Type 'number' is not assignable to type 'number[]'. tests/cases/compiler/arraySigChecking.ts(22,16): error TS2322: Type 'number' is not assignable to type 'number[]'. @@ -17,7 +17,7 @@ tests/cases/compiler/arraySigChecking.ts(22,16): error TS2322: Type 'number' is var foo: { [index: any]; }; // expect an error here ~~~~~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. } interface myInt { diff --git a/tests/baselines/reference/bigintIndex.errors.txt b/tests/baselines/reference/bigintIndex.errors.txt index 216e2d4857f07..b2b1c197642cf 100644 --- a/tests/baselines/reference/bigintIndex.errors.txt +++ b/tests/baselines/reference/bigintIndex.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/a.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/a.ts(2,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/a.ts(8,11): error TS2538: Type '1n' cannot be used as an index type. tests/cases/compiler/a.ts(14,1): error TS2322: Type 'bigint' is not assignable to type 'string | number | symbol'. tests/cases/compiler/a.ts(19,12): error TS2538: Type 'bigint' cannot be used as an index type. @@ -13,7 +13,7 @@ tests/cases/compiler/b.ts(4,12): error TS2464: A computed property name must be interface BigIntIndex { [index: bigint]: E; // should error ~~~~~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. } const arr: number[] = [1, 2, 3]; diff --git a/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt b/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt index 2e116a25861e2..3a127ef6e781c 100644 --- a/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt +++ b/tests/baselines/reference/declarationEmitIndexTypeNotFound.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(2,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(2,13): error TS2304: Cannot find name 'TypeNotFound'. tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(2,13): error TS4092: Parameter 'index' of index signature from exported interface has or is using private name 'TypeNotFound'. @@ -7,7 +7,7 @@ tests/cases/compiler/declarationEmitIndexTypeNotFound.ts(2,13): error TS4092: Pa export interface Test { [index: TypeNotFound]: any; ~~~~~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ~~~~~~~~~~~~ !!! error TS2304: Cannot find name 'TypeNotFound'. ~~~~~~~~~~~~ diff --git a/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt b/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt index 36f2bf9fbdaf7..850190d1552c0 100644 --- a/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt +++ b/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/genericIndexTypeHasSensibleErrorMessage.ts(1,33): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/genericIndexTypeHasSensibleErrorMessage.ts(1,33): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ==== tests/cases/compiler/genericIndexTypeHasSensibleErrorMessage.ts (1 errors) ==== type Wat = { [x: T]: string }; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. \ No newline at end of file +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. \ No newline at end of file diff --git a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.d.errors.txt b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.d.errors.txt index 14107cde7e176..19f6ded5819fd 100644 --- a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.d.errors.txt +++ b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.d.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(10,21): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(11,22): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(11,26): error TS2314: Generic type 'C' requires 1 type argument(s). -tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,19): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,19): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,22): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,26): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(14,23): error TS2314: Generic type 'C' requires 1 type argument(s). @@ -36,7 +36,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc !!! error TS2314: Generic type 'C' requires 1 type argument(s). declare var d: { [x: C]: C }; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ~ !!! error TS2314: Generic type 'C' requires 1 type argument(s). ~ diff --git a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.errors.txt b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.errors.txt index 68d91622a310f..55e3d89149d15 100644 --- a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.errors.txt +++ b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(10,13): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(11,14): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(11,18): error TS2314: Generic type 'C' requires 1 type argument(s). -tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,11): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,11): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,14): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,18): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(14,13): error TS2314: Generic type 'C' requires 1 type argument(s). @@ -46,7 +46,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc !!! error TS2314: Generic type 'C' requires 1 type argument(s). var d: { [x: C]: C }; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ~ !!! error TS2314: Generic type 'C' requires 1 type argument(s). ~ diff --git a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt index 7a63caeaf670c..bb4ea837feba9 100644 --- a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt +++ b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(10,13): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(11,14): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(11,18): error TS2314: Generic type 'I' requires 1 type argument(s). -tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,11): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,11): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,14): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,18): error TS2314: Generic type 'I' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(14,13): error TS2314: Generic type 'I' requires 1 type argument(s). @@ -46,7 +46,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc !!! error TS2314: Generic type 'I' requires 1 type argument(s). var d: { [x: I]: I }; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ~ !!! error TS2314: Generic type 'I' requires 1 type argument(s). ~ diff --git a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument3.errors.txt b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument3.errors.txt index bb6ee2494add0..b7bdf099c2053 100644 --- a/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument3.errors.txt +++ b/tests/baselines/reference/genericTypeReferenceWithoutTypeArgument3.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(10,21): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(11,22): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(11,26): error TS2314: Generic type 'C' requires 1 type argument(s). -tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,19): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,19): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,22): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,26): error TS2314: Generic type 'C' requires 1 type argument(s). tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(14,23): error TS2314: Generic type 'C' requires 1 type argument(s). @@ -36,7 +36,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc !!! error TS2314: Generic type 'C' requires 1 type argument(s). declare var d: { [x: C]: C }; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ~ !!! error TS2314: Generic type 'C' requires 1 type argument(s). ~ diff --git a/tests/baselines/reference/indexTypeCheck.errors.txt b/tests/baselines/reference/indexTypeCheck.errors.txt index c5c16f5ecd914..ea2e14103323f 100644 --- a/tests/baselines/reference/indexTypeCheck.errors.txt +++ b/tests/baselines/reference/indexTypeCheck.errors.txt @@ -4,7 +4,7 @@ tests/cases/compiler/indexTypeCheck.ts(17,2): error TS2413: Numeric index type ' tests/cases/compiler/indexTypeCheck.ts(22,2): error TS2413: Numeric index type 'Orange' is not assignable to string index type 'Yellow'. tests/cases/compiler/indexTypeCheck.ts(27,2): error TS2413: Numeric index type 'number' is not assignable to string index type 'string'. tests/cases/compiler/indexTypeCheck.ts(32,3): error TS1096: An index signature must have exactly one parameter. -tests/cases/compiler/indexTypeCheck.ts(36,3): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/indexTypeCheck.ts(36,3): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/indexTypeCheck.ts(51,8): error TS2538: Type 'Blue' cannot be used as an index type. @@ -58,7 +58,7 @@ tests/cases/compiler/indexTypeCheck.ts(51,8): error TS2538: Type 'Blue' cannot b interface Magenta { [p:Purple]; // error ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. } var yellow: Yellow; diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index b3bd692122efd..5a4dca341b28a 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -1,18 +1,16 @@ tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[n: number]: A' instead. -tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[s: string]: A' instead. -tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. -tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. tests/cases/compiler/indexerConstraints2.ts(74,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. -tests/cases/compiler/indexerConstraints2.ts(79,6): error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[key: string]: any' instead. +tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signature must have a type annotation. -==== tests/cases/compiler/indexerConstraints2.ts (12 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (10 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -53,16 +51,12 @@ tests/cases/compiler/indexerConstraints2.ts(79,6): error TS1336: An index signat interface L { [n: AliasedNumber]: A; - ~ -!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[n: number]: A' instead. } type AliasedString = string; interface M { [s: AliasedString]: A; - ~ -!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[s: string]: A' instead. } type AliasedBoolean = boolean; @@ -70,7 +64,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,6): error TS1336: An index signat interface N { [b: AliasedBoolean]: A; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. } type IndexableUnion = "foo" | "bar"; @@ -86,7 +80,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,6): error TS1336: An index signat interface P { [u: NonIndexableUnion]: A; ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. } type NonIndexableUnion2 = string | number; @@ -114,7 +108,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,6): error TS1336: An index signat type Key = string; interface T { [key: Key] - ~~~ -!!! error TS1336: An index signature parameter type cannot be a type alias. Consider writing '[key: string]: any' instead. + ~~~~~~~~~~ +!!! error TS1021: An index signature must have a type annotation. } \ No newline at end of file diff --git a/tests/baselines/reference/parserES5SymbolIndexer1.errors.txt b/tests/baselines/reference/parserES5SymbolIndexer1.errors.txt deleted file mode 100644 index a0010dc0a27a4..0000000000000 --- a/tests/baselines/reference/parserES5SymbolIndexer1.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer1.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer1.ts (1 errors) ==== - interface I { - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserES5SymbolIndexer2.errors.txt b/tests/baselines/reference/parserES5SymbolIndexer2.errors.txt deleted file mode 100644 index acc43ed9b74e2..0000000000000 --- a/tests/baselines/reference/parserES5SymbolIndexer2.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer2.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer2.ts (1 errors) ==== - class C { - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserES5SymbolIndexer3.errors.txt b/tests/baselines/reference/parserES5SymbolIndexer3.errors.txt deleted file mode 100644 index 12d8819c60130..0000000000000 --- a/tests/baselines/reference/parserES5SymbolIndexer3.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer3.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript5/Symbols/parserES5SymbolIndexer3.ts (1 errors) ==== - var x: { - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserIndexSignature6.errors.txt b/tests/baselines/reference/parserIndexSignature6.errors.txt index 9df13e05b6c87..8ece1d1190fe0 100644 --- a/tests/baselines/reference/parserIndexSignature6.errors.txt +++ b/tests/baselines/reference/parserIndexSignature6.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature6.ts(2,4): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature6.ts(2,4): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ==== tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature6.ts (1 errors) ==== interface I { [a:boolean] ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. } \ No newline at end of file diff --git a/tests/baselines/reference/parserIndexSignature8.errors.txt b/tests/baselines/reference/parserIndexSignature8.errors.txt index 5ca6f11573fee..b1c80679bc091 100644 --- a/tests/baselines/reference/parserIndexSignature8.errors.txt +++ b/tests/baselines/reference/parserIndexSignature8.errors.txt @@ -1,12 +1,12 @@ -tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature8.ts(1,13): error TS1023: An index signature parameter type must be either 'string' or 'number'. -tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature8.ts(2,14): error TS1023: An index signature parameter type must be either 'string' or 'number'. +tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature8.ts(1,13): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. +tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature8.ts(2,14): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. ==== tests/cases/conformance/parser/ecmascript5/IndexSignatures/parserIndexSignature8.ts (2 errors) ==== var foo: { [index: any]; }; // expect an error here ~~~~~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. var foo2: { [index: RegExp]; }; // expect an error here ~~~~~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. \ No newline at end of file diff --git a/tests/baselines/reference/parserSymbolIndexer1.errors.txt b/tests/baselines/reference/parserSymbolIndexer1.errors.txt deleted file mode 100644 index b9a34890151d7..0000000000000 --- a/tests/baselines/reference/parserSymbolIndexer1.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer1.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer1.ts (1 errors) ==== - interface I { - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserSymbolIndexer2.errors.txt b/tests/baselines/reference/parserSymbolIndexer2.errors.txt deleted file mode 100644 index 3b8735feef9ac..0000000000000 --- a/tests/baselines/reference/parserSymbolIndexer2.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer2.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer2.ts (1 errors) ==== - class C { - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserSymbolIndexer3.errors.txt b/tests/baselines/reference/parserSymbolIndexer3.errors.txt deleted file mode 100644 index 617d72614658c..0000000000000 --- a/tests/baselines/reference/parserSymbolIndexer3.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer3.ts(2,13): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer3.ts (1 errors) ==== - class C { - static [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserSymbolIndexer4.errors.txt b/tests/baselines/reference/parserSymbolIndexer4.errors.txt deleted file mode 100644 index 4da102891a0fd..0000000000000 --- a/tests/baselines/reference/parserSymbolIndexer4.errors.txt +++ /dev/null @@ -1,9 +0,0 @@ -tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer4.ts(2,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer4.ts (1 errors) ==== - var x: { - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty17.errors.txt b/tests/baselines/reference/symbolProperty17.errors.txt deleted file mode 100644 index a28a1d0981041..0000000000000 --- a/tests/baselines/reference/symbolProperty17.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/es6/Symbols/symbolProperty17.ts(3,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/es6/Symbols/symbolProperty17.ts (1 errors) ==== - interface I { - [Symbol.iterator]: number; - [s: symbol]: string; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - "__@iterator": string; - } - - var i: I; - var it = i[Symbol.iterator]; \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty29.errors.txt b/tests/baselines/reference/symbolProperty29.errors.txt deleted file mode 100644 index b0f6bb3bc3169..0000000000000 --- a/tests/baselines/reference/symbolProperty29.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -tests/cases/conformance/es6/Symbols/symbolProperty29.ts(5,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/es6/Symbols/symbolProperty29.ts (1 errors) ==== - class C1 { - [Symbol.toStringTag]() { - return { x: "" }; - } - [s: symbol]: () => { x: string }; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty30.errors.txt b/tests/baselines/reference/symbolProperty30.errors.txt deleted file mode 100644 index c986fd28641be..0000000000000 --- a/tests/baselines/reference/symbolProperty30.errors.txt +++ /dev/null @@ -1,12 +0,0 @@ -tests/cases/conformance/es6/Symbols/symbolProperty30.ts(5,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/es6/Symbols/symbolProperty30.ts (1 errors) ==== - class C1 { - [Symbol.toStringTag]() { - return { x: "" }; - } - [s: symbol]: () => { x: number }; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty31.errors.txt b/tests/baselines/reference/symbolProperty31.errors.txt deleted file mode 100644 index 46a6177809016..0000000000000 --- a/tests/baselines/reference/symbolProperty31.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/es6/Symbols/symbolProperty31.ts(7,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/es6/Symbols/symbolProperty31.ts (1 errors) ==== - class C1 { - [Symbol.toStringTag]() { - return { x: "" }; - } - } - class C2 extends C1 { - [s: symbol]: () => { x: string }; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty32.errors.txt b/tests/baselines/reference/symbolProperty32.errors.txt deleted file mode 100644 index 3318459b29404..0000000000000 --- a/tests/baselines/reference/symbolProperty32.errors.txt +++ /dev/null @@ -1,14 +0,0 @@ -tests/cases/conformance/es6/Symbols/symbolProperty32.ts(7,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. - - -==== tests/cases/conformance/es6/Symbols/symbolProperty32.ts (1 errors) ==== - class C1 { - [Symbol.toStringTag]() { - return { x: "" }; - } - } - class C2 extends C1 { - [s: symbol]: () => { x: number }; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. - } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty33.errors.txt b/tests/baselines/reference/symbolProperty33.errors.txt index 09b32a501ce93..1f3432759fdb5 100644 --- a/tests/baselines/reference/symbolProperty33.errors.txt +++ b/tests/baselines/reference/symbolProperty33.errors.txt @@ -1,8 +1,7 @@ tests/cases/conformance/es6/Symbols/symbolProperty33.ts(1,18): error TS2449: Class 'C2' used before its declaration. -tests/cases/conformance/es6/Symbols/symbolProperty33.ts(7,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. -==== tests/cases/conformance/es6/Symbols/symbolProperty33.ts (2 errors) ==== +==== tests/cases/conformance/es6/Symbols/symbolProperty33.ts (1 errors) ==== class C1 extends C2 { ~~ !!! error TS2449: Class 'C2' used before its declaration. @@ -13,6 +12,4 @@ tests/cases/conformance/es6/Symbols/symbolProperty33.ts(7,6): error TS1023: An i } class C2 { [s: symbol]: () => { x: string }; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty34.errors.txt b/tests/baselines/reference/symbolProperty34.errors.txt index 390ead2177f04..6adbeb6fa7afb 100644 --- a/tests/baselines/reference/symbolProperty34.errors.txt +++ b/tests/baselines/reference/symbolProperty34.errors.txt @@ -1,8 +1,7 @@ tests/cases/conformance/es6/Symbols/symbolProperty34.ts(1,18): error TS2449: Class 'C2' used before its declaration. -tests/cases/conformance/es6/Symbols/symbolProperty34.ts(7,6): error TS1023: An index signature parameter type must be either 'string' or 'number'. -==== tests/cases/conformance/es6/Symbols/symbolProperty34.ts (2 errors) ==== +==== tests/cases/conformance/es6/Symbols/symbolProperty34.ts (1 errors) ==== class C1 extends C2 { ~~ !!! error TS2449: Class 'C2' used before its declaration. @@ -13,6 +12,4 @@ tests/cases/conformance/es6/Symbols/symbolProperty34.ts(7,6): error TS1023: An i } class C2 { [s: symbol]: () => { x: number }; - ~ -!!! error TS1023: An index signature parameter type must be either 'string' or 'number'. } \ No newline at end of file From 8622ae681c3cc5e05771ae67edbca10619325595 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 2 Jun 2021 09:39:56 -0700 Subject: [PATCH 08/56] Consider all index signatures in mapped types and union types --- src/compiler/checker.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bd568990d041..2e54214fc9ebb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11052,11 +11052,15 @@ namespace ts { for (const prop of getPropertiesOfType(modifiersType)) { addMemberForKeyType(getLiteralTypeFromProperty(prop, include)); } - if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, stringType)) { + if (modifiersType.flags & TypeFlags.Any) { addMemberForKeyType(stringType); } - if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, numberType)) { - addMemberForKeyType(numberType); + else { + for (const info of getIndexInfosOfType(modifiersType)) { + if (!keyofStringsOnly || info.keyType.flags & (TypeFlags.String | TypeFlags.TemplateLiteral)) { + addMemberForKeyType(info.keyType); + } + } } } else { @@ -11281,7 +11285,7 @@ namespace ts { } // The properties of a union type are those that are present in all constituent types, so // we only need to check the properties of the first type without index signature - if (type.flags & TypeFlags.Union && !getIndexInfoOfType(current, stringType) && !getIndexInfoOfType(current, numberType)) { + if (type.flags & TypeFlags.Union && getIndexInfosOfType(current).length === 0) { break; } } @@ -11727,7 +11731,7 @@ namespace ts { } } else if (isUnion) { - const indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, numberType) || getIndexInfoOfType(type, stringType)); + const indexInfo = !isLateBoundName(name) && getApplicableIndexInfo(type, getLiteralType(isNumericLiteralName(name) ? +name : unescapeLeadingUnderscores(name))); if (indexInfo) { checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0); indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); @@ -15430,7 +15434,7 @@ namespace ts { const members = createSymbolTable(); const skippedPrivateMembers = new Set<__String>(); - let indexInfos = left === emptyObjectType ? getIndexInfosOfType(right) : getUnionIndexInfos([left, right]); + const indexInfos = left === emptyObjectType ? getIndexInfosOfType(right) : getUnionIndexInfos([left, right]); for (const rightProp of getPropertiesOfType(right)) { if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) { From 7285cb9f307fe2c6f6c5954d749e742d601a61ca Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 2 Jun 2021 09:40:02 -0700 Subject: [PATCH 09/56] Accept new baselines --- tests/baselines/reference/keyofAndIndexedAccess.types | 6 +++--- tests/baselines/reference/keyofAndIndexedAccessErrors.types | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index c90e635247a7b..79e1f321c3e6f 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -58,10 +58,10 @@ type K00 = keyof any; // string >K00 : string | number | symbol type K01 = keyof string; // "toString" | "charAt" | ... ->K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "valueOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ... ->K02 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" +>K02 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" type K03 = keyof boolean; // "valueOf" >K03 : "valueOf" @@ -98,7 +98,7 @@ type K14 = keyof Object; // "constructor" | "toString" | ... >K14 : keyof Object type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... ->K15 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" +>K15 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... >K16 : number | keyof [string, number] diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 27f0642094e45..6fb2b69bfad91 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -26,19 +26,19 @@ type T01 = keyof Object; >T01 : keyof Object type T02 = keyof keyof Object; ->T02 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T02 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type T03 = keyof keyof keyof Object; >T03 : "toString" | "valueOf" type T04 = keyof keyof keyof keyof Object; ->T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T04 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type T05 = keyof keyof keyof keyof keyof Object; >T05 : "toString" | "valueOf" type T06 = keyof keyof keyof keyof keyof keyof Object; ->T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T06 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type T10 = Shape["name"]; >T10 : string From 4bd05bcf3c2be1b47d2cd0d6049aa2007d0fe1bc Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 2 Jun 2021 15:54:39 -0700 Subject: [PATCH 10/56] Update getIndexType --- src/compiler/checker.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2e54214fc9ebb..7b192fe5fe113 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -766,6 +766,7 @@ namespace ts { const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); const unreachableNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); + const stringOrNumberType = getUnionType([stringType, numberType]); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; const numberOrBigIntType = getUnionType([numberType, bigintType]); @@ -14356,7 +14357,10 @@ namespace ts { function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeOrigin: boolean) { const origin = includeOrigin && (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference) || type.aliasSymbol) ? createOriginIndexType(type) : undefined; - return getUnionType(map(getPropertiesOfType(type), p => getLiteralTypeFromProperty(p, include)), UnionReduction.Literal, + const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, include)); + const indexKeyTypes = map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && info.keyType.flags & include ? + info.keyType === stringType && include & TypeFlags.Number ? stringOrNumberType : info.keyType : neverType); + return getUnionType(concatenate(propertyTypes, indexKeyTypes), UnionReduction.Literal, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, origin); } @@ -14366,7 +14370,6 @@ namespace ts { } function getIndexType(type: Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): Type { - const includeOrigin = stringsOnly === keyofStringsOnly && !noIndexSignatures; type = getReducedType(type); return type.flags & TypeFlags.Union ? getIntersectionType(map((type as UnionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type as IntersectionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : @@ -14375,10 +14378,8 @@ namespace ts { type === wildcardType ? wildcardType : type.flags & TypeFlags.Unknown ? neverType : type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType : - stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, stringType) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral, includeOrigin) : - !noIndexSignatures && getIndexInfoOfType(type, stringType) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol, includeOrigin)]) : - getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol, includeOrigin)]) : - getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique, includeOrigin); + getLiteralTypeFromProperties(type, (noIndexSignatures ? TypeFlags.StringLiteral : TypeFlags.StringLike) | (stringsOnly ? 0 : TypeFlags.NumberLike | TypeFlags.ESSymbolLike), + stringsOnly === keyofStringsOnly && !noIndexSignatures); } function getExtractStringType(type: Type) { From a91782f01ec5395f5233cf149041a4f2b9a3ce1d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 2 Jun 2021 15:55:05 -0700 Subject: [PATCH 11/56] Accept new baselines --- tests/baselines/reference/deepKeysIndexing.types | 12 ++++++------ .../baselines/reference/keyofAndIndexedAccess.types | 4 ++-- tests/baselines/reference/variadicTuples1.errors.txt | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/baselines/reference/deepKeysIndexing.types b/tests/baselines/reference/deepKeysIndexing.types index 73189b504da10..fed261833cdd8 100644 --- a/tests/baselines/reference/deepKeysIndexing.types +++ b/tests/baselines/reference/deepKeysIndexing.types @@ -92,27 +92,27 @@ const bar = new Bar(); // all 3 of the below should error on passing `true` for `"1"` bar.broken("a", "1", true); // was broken in the past - with 2nd argument incorrectly of type "1" | "2" | "3". >bar.broken("a", "1", true) : void ->bar.broken : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void +>bar.broken : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void >bar : Bar ->broken : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void +>broken : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void >"a" : "a" >"1" : "1" >true : true bar.working("a", "1", true); // ok - true is not allowed >bar.working("a", "1", true) : void ->bar.working : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void +>bar.working : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void >bar : Bar ->working : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void +>working : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void >"a" : "a" >"1" : "1" >true : true bar.workaround("a", "1", true); // ok - true is not allowed >bar.workaround("a", "1", true) : void ->bar.workaround : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void +>bar.workaround : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void >bar : Bar ->workaround : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void +>workaround : , V extends Foo[K1][K2]>(k1: K1, k2: K2, value: V) => void >"a" : "a" >"1" : "1" >true : true diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 79e1f321c3e6f..47a7cbfdbd635 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -86,7 +86,7 @@ type K10 = keyof Shape; // "name" | "width" | "height" | "visible" >K10 : keyof Shape type K11 = keyof Shape[]; // "length" | "toString" | ... ->K11 : number | keyof Shape[] +>K11 : keyof Shape[] type K12 = keyof Dictionary; // string >K12 : string | number @@ -101,7 +101,7 @@ type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... >K15 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... ->K16 : number | keyof [string, number] +>K16 : keyof [string, number] type K17 = keyof (Shape | Item); // "name" >K17 : "name" diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 956bd6a922be2..b917aa585d2a3 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -33,7 +33,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. - Type '"2"' is not assignable to type 'number | "0" | keyof T[] | "1"'. + Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number | undefined'. tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. Type at position 0 in source is not compatible with type at position 0 in target. @@ -298,7 +298,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Typ k3 = '2'; // Error ~~ !!! error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. -!!! error TS2322: Type '"2"' is not assignable to type 'number | "0" | keyof T[] | "1"'. +!!! error TS2322: Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. } // Inference between variadic tuple types From 730ded4eac50135c0f4d846028ca842872a60167 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 3 Jun 2021 09:59:59 -0700 Subject: [PATCH 12/56] Intersect multiple applicable index signatures --- src/compiler/checker.ts | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7b192fe5fe113..afa0266f33793 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12023,8 +12023,29 @@ namespace ts { function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { const indexInfos = getIndexInfosOfType(type); - return find(indexInfos, info => info.keyType !== stringType && isTypeAssignableTo(keyType, info.keyType)) || - findIndexInfo(indexInfos, stringType); + let stringIndexInfo: IndexInfo | undefined; + let applicableInfo: IndexInfo | undefined; + let applicableInfos: IndexInfo[] | undefined; + for (const info of indexInfos) { + if (info.keyType === stringType) { + stringIndexInfo = info; + } + else if (isTypeAssignableTo(keyType, info.keyType)) { + if (!applicableInfo) { + applicableInfo = info; + } + else { + (applicableInfos || (applicableInfos = [applicableInfo])).push(info); + } + } + } + // When more than one index signature is applicable we create a synthetic IndexInfo. Instead of computing + // the intersected key type, we just use unknownType for the key type as nothing actually depends on the + // keyType property of the returned IndexInfo. + return applicableInfos ? + createIndexInfo(unknownType, getIntersectionType(map(applicableInfos, info => info.type)), + /*isReadonly */ reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, true)) : + applicableInfo || stringIndexInfo; } // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual @@ -14645,7 +14666,7 @@ namespace ts { } const indexInfo = getApplicableIndexInfo(objectType, indexType); if (indexInfo) { - if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo.keyType === stringType) { + if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo.keyType !== numberType) { if (accessExpression) { error(accessExpression, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType)); } From c6cc9a15ca1b7005f20a1473c6f3f5428295c4d1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 3 Jun 2021 14:06:15 -0700 Subject: [PATCH 13/56] Use getApplicableIndexInfo instead of hardwired string/number handling --- src/compiler/checker.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index afa0266f33793..7e661fc389414 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8127,7 +8127,7 @@ namespace ts { } function getTypeOfPropertyOrIndexSignature(type: Type, name: __String): Type { - return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, numberType) || getIndexTypeOfType(type, stringType) || unknownType; + return getTypeOfPropertyOfType(type, name) || getApplicableIndexInfoForName(type, name)?.type || unknownType; } function isTypeAny(type: Type | undefined) { @@ -12044,10 +12044,14 @@ namespace ts { // keyType property of the returned IndexInfo. return applicableInfos ? createIndexInfo(unknownType, getIntersectionType(map(applicableInfos, info => info.type)), - /*isReadonly */ reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, true)) : + reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, /*initial*/ true)) : applicableInfo || stringIndexInfo; } + function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined { + return isNumericLiteralName(name) && getIndexInfoOfType(type, numberType) || getApplicableIndexInfo(type, getLiteralType(unescapeLeadingUnderscores(name))); + } + // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual // type checking functions). function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] | undefined { @@ -16702,9 +16706,7 @@ namespace ts { let issuedElaboration = false; if (!targetProp) { - const indexInfo = isTypeAssignableToKind(nameType, TypeFlags.NumberLike) && getIndexInfoOfType(target, numberType) || - getIndexInfoOfType(target, stringType) || - undefined; + const indexInfo = getApplicableIndexInfo(target, nameType); if (indexInfo && indexInfo.declaration && !getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) { issuedElaboration = true; addRelatedInfo(reportedDiag, createDiagnosticForNode(indexInfo.declaration, Diagnostics.The_expected_type_comes_from_this_index_signature)); @@ -17186,7 +17188,7 @@ namespace ts { } function isStringIndexSignatureOnlyType(type: Type): boolean { - return type.flags & TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, stringType) && !getIndexInfoOfType(type, numberType) || + return type.flags & TypeFlags.Object && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfosOfType(type).length === 1 && !!getIndexInfoOfType(type, stringType) || type.flags & TypeFlags.UnionOrIntersection && every((type as UnionOrIntersectionType).types, isStringIndexSignatureOnlyType) || false; } @@ -17900,7 +17902,7 @@ namespace ts { const appendPropType = (propTypes: Type[] | undefined, type: Type) => { type = getApparentType(type); const prop = type.flags & TypeFlags.UnionOrIntersection ? getPropertyOfUnionOrIntersectionType(type as UnionOrIntersectionType, name) : getPropertyOfObjectType(type, name); - const propType = prop && getTypeOfSymbol(prop) || isNumericLiteralName(name) && getIndexTypeOfType(type, numberType) || getIndexTypeOfType(type, stringType) || undefinedType; + const propType = prop && getTypeOfSymbol(prop) || getApplicableIndexInfoForName(type, name)?.type || undefinedType; return append(propTypes, propType); }; return getUnionType(reduceLeft(types, appendPropType, /*initial*/ undefined) || emptyArray); @@ -22285,10 +22287,7 @@ namespace ts { const nameType = getLiteralTypeFromPropertyName(name); if (!isTypeUsableAsPropertyName(nameType)) return errorType; const text = getPropertyNameFromType(nameType); - return getTypeOfPropertyOfType(type, text) || - isNumericLiteralName(text) && includeUndefinedInIndexSignature(getIndexTypeOfType(type, numberType)) || - includeUndefinedInIndexSignature(getIndexTypeOfType(type, stringType)) || - errorType; + return getTypeOfPropertyOfType(type, text) || includeUndefinedInIndexSignature(getApplicableIndexInfoForName(type, text)?.type) || errorType; } function getTypeOfDestructuredArrayElement(type: Type, index: number) { @@ -27394,7 +27393,8 @@ namespace ts { let propType: Type; if (!prop) { - const indexInfo = !isPrivateIdentifier(right) && (assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? getIndexInfoOfType(apparentType, stringType) : undefined; + const indexInfo = !isPrivateIdentifier(right) && (assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? + getApplicableIndexInfoForName(apparentType, right.escapedText) : undefined; if (!(indexInfo && indexInfo.type)) { if (isJSLiteralType(leftType)) { return anyType; @@ -27576,7 +27576,7 @@ namespace ts { let relatedInfo: Diagnostic | undefined; if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) { for (const subtype of (containingType as UnionType).types) { - if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, stringType)) { + if (!getPropertyOfType(subtype, propNode.escapedText) && !getApplicableIndexInfoForName(subtype, propNode.escapedText)) { errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(subtype)); break; } @@ -27868,7 +27868,7 @@ namespace ts { * Return true if the given type is considered to have numeric property names. */ function hasNumericPropertyNames(type: Type) { - return getIndexTypeOfType(type, numberType) && !getIndexTypeOfType(type, stringType); + return getIndexInfosOfType(type).length === 1 && !!getIndexInfoOfType(type, numberType); } /** From bed92640f32f760d506d585292983dd63086845c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 4 Jun 2021 07:37:44 -0700 Subject: [PATCH 14/56] Update index signature relationship checking --- src/compiler/checker.ts | 98 ++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7e661fc389414..0604b82f9ae7e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18723,10 +18723,7 @@ namespace ts { if (result) { result &= signaturesRelatedTo(source, target, SignatureKind.Construct, reportStructuralErrors); if (result) { - result &= indexTypesRelatedTo(source, target, stringType, sourceIsPrimitive, reportStructuralErrors, intersectionState); - if (result) { - result &= indexTypesRelatedTo(source, target, numberType, sourceIsPrimitive, reportStructuralErrors, intersectionState); - } + result &= indexSignaturesRelatedTo(source, target, sourceIsPrimitive, reportStructuralErrors, intersectionState); } } } @@ -18914,15 +18911,12 @@ namespace ts { result &= signaturesRelatedTo(source, type, SignatureKind.Call, /*reportStructuralErrors*/ false); if (result) { result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false); - if (result) { - result &= indexTypesRelatedTo(source, type, stringType, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); + if (result && !(isTupleType(source) && isTupleType(type))) { // Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the // element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems // with index type assignability as the types for the excluded discriminants are still included // in the index type. - if (result && !(isTupleType(source) && isTupleType(type))) { - result &= indexTypesRelatedTo(source, type, numberType, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); - } + result &= indexSignaturesRelatedTo(source, type, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, IntersectionState.None); } } } @@ -19402,8 +19396,9 @@ namespace ts { return result; } - function eachPropertyRelatedTo(source: Type, target: Type, keyType: Type, reportErrors: boolean): Ternary { + function membersRelatedToIndexInfo(source: Type, targetInfo: IndexInfo, reportErrors: boolean): Ternary { let result = Ternary.True; + const keyType = targetInfo.keyType; const props = source.flags & TypeFlags.Intersection ? getPropertiesOfUnionOrIntersectionType(source as IntersectionType) : getPropertiesOfObjectType(source); for (const prop of props) { // Skip over ignored JSX and symbol-named members @@ -19414,12 +19409,13 @@ namespace ts { if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) { continue; } - if (keyType === stringType || isNumericLiteralName(prop.escapedName)) { + if (keyType === stringType || keyType === numberType && isNumericLiteralName(prop.escapedName) || + isTypeAssignableTo(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), keyType)) { const propType = getTypeOfSymbol(prop); const type = propType.flags & TypeFlags.Undefined || !(keyType === stringType && prop.flags & SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); - const related = isRelatedTo(type, target, reportErrors); + const related = isRelatedTo(type, targetInfo.type, reportErrors); if (!related) { if (reportErrors) { reportError(Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop)); @@ -19429,6 +19425,15 @@ namespace ts { result &= related; } } + for (const info of getIndexInfosOfType(source)) { + if (isTypeAssignableTo(info.keyType, keyType)) { + const related = indexTypeRelatedTo(info.type, targetInfo.type, reportErrors); + if (!related) { + return Ternary.False; + } + result &= related; + } + } return result; } @@ -19440,43 +19445,33 @@ namespace ts { return related; } - function indexTypesRelatedTo(source: Type, target: Type, keyType: Type, sourceIsPrimitive: boolean, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + function indexSignaturesRelatedTo(source: Type, target: Type, sourceIsPrimitive: boolean, reportErrors: boolean, intersectionState: IntersectionState): Ternary { if (relation === identityRelation) { - return indexTypesIdenticalTo(source, target, keyType); - } - const targetType = getIndexTypeOfType(target, keyType); - if (!targetType) { - return Ternary.True; + return indexSignaturesIdenticalTo(source, target); } - if (targetType.flags & TypeFlags.Any && !sourceIsPrimitive) { - // An index signature of type `any` permits assignment from everything but primitives, - // provided that there is also a `string` index signature of type `any`. - const stringIndexType = keyType === stringType ? targetType : getIndexTypeOfType(target, stringType); - if (stringIndexType && stringIndexType.flags & TypeFlags.Any) { - return Ternary.True; + const indexInfos = getIndexInfosOfType(target); + const targetHasStringIndex = some(indexInfos, info => info.keyType === stringType); + let result = Ternary.True; + for (const targetInfo of indexInfos) { + const related = !sourceIsPrimitive && targetHasStringIndex && targetInfo.type.flags & TypeFlags.Any ? Ternary.True : + isGenericMappedType(source) && targetHasStringIndex ? isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors) : + typeRelatedToIndexInfo(source, targetInfo, reportErrors, intersectionState); + if (!related) { + return Ternary.False; } - - } - if (isGenericMappedType(source)) { - // A generic mapped type { [P in K]: T } is related to a type with an index signature - // { [x: string]: U }, and optionally with an index signature { [x: number]: V }, - // if T is related to U and V. - return getIndexTypeOfType(target, stringType) ? isRelatedTo(getTemplateTypeFromMappedType(source), targetType, reportErrors) : Ternary.False; + result &= related; } - const indexType = getIndexTypeOfType(source, keyType) || keyType === numberType && getIndexTypeOfType(source, stringType); - if (indexType) { - return indexTypeRelatedTo(indexType, targetType, reportErrors); + return result; + } + + function typeRelatedToIndexInfo(source: Type, targetInfo: IndexInfo, reportErrors: boolean, intersectionState: IntersectionState): Ternary { + const sourceInfo = getApplicableIndexInfo(source, targetInfo.keyType); + if (sourceInfo) { + return indexTypeRelatedTo(sourceInfo.type, targetInfo.type, reportErrors); } if (!(intersectionState & IntersectionState.Source) && isObjectTypeWithInferableIndex(source)) { // Intersection constituents are never considered to have an inferred index signature - let related = eachPropertyRelatedTo(source, targetType, keyType, reportErrors); - if (related && keyType === stringType) { - const numberIndexType = getIndexTypeOfType(source, numberType); - if (numberIndexType) { - related &= indexTypeRelatedTo(numberIndexType, targetType, reportErrors); - } - } - return related; + return membersRelatedToIndexInfo(source, targetInfo, reportErrors); } if (reportErrors) { reportError(Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source)); @@ -19484,16 +19479,19 @@ namespace ts { return Ternary.False; } - function indexTypesIdenticalTo(source: Type, target: Type, keyType: Type): Ternary { - const targetInfo = getIndexInfoOfType(target, keyType); - const sourceInfo = getIndexInfoOfType(source, keyType); - if (!sourceInfo && !targetInfo) { - return Ternary.True; + function indexSignaturesIdenticalTo(source: Type, target: Type): Ternary { + const sourceInfos = getIndexInfosOfType(source); + const targetInfos = getIndexInfosOfType(target); + if (sourceInfos.length !== targetInfos.length) { + return Ternary.False; } - if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) { - return isRelatedTo(sourceInfo.type, targetInfo.type); + for (const targetInfo of targetInfos) { + const sourceInfo = getIndexInfoOfType(source, targetInfo.keyType); + if (!(sourceInfo && isRelatedTo(sourceInfo.type, targetInfo.type) && sourceInfo.isReadonly === targetInfo.isReadonly)) { + return Ternary.False; + } } - return Ternary.False; + return Ternary.True; } function constructorVisibilitiesAreCompatible(sourceSignature: Signature, targetSignature: Signature, reportErrors: boolean) { From cf0b614d2377ceaf400d792f1c95d5fe49b072ff Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 4 Jun 2021 07:51:19 -0700 Subject: [PATCH 15/56] Report type for which index signature is missing --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0604b82f9ae7e..0136173c1a84e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19474,7 +19474,7 @@ namespace ts { return membersRelatedToIndexInfo(source, targetInfo, reportErrors); } if (reportErrors) { - reportError(Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source)); + reportError(Diagnostics.Index_signature_for_type_0_is_missing_in_type_1, typeToString(targetInfo.keyType), typeToString(source)); } return Ternary.False; } From 2c0bf2b20f6644ae09dc00db04d7bfa0d99cab79 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 4 Jun 2021 07:51:42 -0700 Subject: [PATCH 16/56] Report type for which index signature is missing --- src/compiler/diagnosticMessages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index dcc8eddb52c57..4749921ca2f81 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1522,7 +1522,7 @@ "category": "Error", "code": 2328 }, - "Index signature is missing in type '{0}'.": { + "Index signature for type '{0}' is missing in type '{1}'.": { "category": "Error", "code": 2329 }, From 041a12f5d5307f39551faf9f042ce55c3425a1d3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 4 Jun 2021 07:51:53 -0700 Subject: [PATCH 17/56] Accept new baselines --- ...tInterfaceWithStringIndexSignature.errors.txt | 4 ++-- .../assignmentCompatability35.errors.txt | 4 ++-- ...TypeAssignmentCompatIndexSignature.errors.txt | 4 ++-- ...eclareClassInterfaceImplementation.errors.txt | 4 ++-- ...ilityWithArrayLike01(strict=false).errors.txt | 4 ++-- ...bilityWithArrayLike01(strict=true).errors.txt | 4 ++-- ...UnknownStillRequiresIndexSignature.errors.txt | 4 ++-- .../indexSignatureTypeInference.errors.txt | 4 ++-- .../jsdocImplements_signatures.errors.txt | 4 ++-- ...StringAndNumberIndexSignatureToAny.errors.txt | 16 ++++++++-------- tests/baselines/reference/parseTypes.errors.txt | 4 ++-- .../stringIndexerAssignments2.errors.txt | 4 ++-- .../subclassThisTypeAssignable01.errors.txt | 8 ++++---- .../reference/underscoreTest1.errors.txt | 4 ++-- .../baselines/reference/unknownType1.errors.txt | 4 ++-- 15 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tests/baselines/reference/assignmentCompatInterfaceWithStringIndexSignature.errors.txt b/tests/baselines/reference/assignmentCompatInterfaceWithStringIndexSignature.errors.txt index 65c1d30779375..4c25dc87decab 100644 --- a/tests/baselines/reference/assignmentCompatInterfaceWithStringIndexSignature.errors.txt +++ b/tests/baselines/reference/assignmentCompatInterfaceWithStringIndexSignature.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/assignmentCompatInterfaceWithStringIndexSignature.ts(15,5): error TS2345: Argument of type 'Foo' is not assignable to parameter of type 'IHandlerMap'. - Index signature is missing in type 'Foo'. + Index signature for type 'string' is missing in type 'Foo'. ==== tests/cases/compiler/assignmentCompatInterfaceWithStringIndexSignature.ts (1 errors) ==== @@ -20,5 +20,5 @@ tests/cases/compiler/assignmentCompatInterfaceWithStringIndexSignature.ts(15,5): Biz(new Foo()); ~~~~~~~~~ !!! error TS2345: Argument of type 'Foo' is not assignable to parameter of type 'IHandlerMap'. -!!! error TS2345: Index signature is missing in type 'Foo'. +!!! error TS2345: Index signature for type 'string' is missing in type 'Foo'. \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatability35.errors.txt b/tests/baselines/reference/assignmentCompatability35.errors.txt index 2073b861f523b..bcfc157148fc2 100644 --- a/tests/baselines/reference/assignmentCompatability35.errors.txt +++ b/tests/baselines/reference/assignmentCompatability35.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/assignmentCompatability35.ts(9,1): error TS2322: Type 'interfaceWithPublicAndOptional' is not assignable to type '{ [index: number]: number; }'. - Index signature is missing in type 'interfaceWithPublicAndOptional'. + Index signature for type 'number' is missing in type 'interfaceWithPublicAndOptional'. ==== tests/cases/compiler/assignmentCompatability35.ts (1 errors) ==== @@ -14,4 +14,4 @@ tests/cases/compiler/assignmentCompatability35.ts(9,1): error TS2322: Type 'inte __test2__.__val__aa = __test1__.__val__obj4 ~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'interfaceWithPublicAndOptional' is not assignable to type '{ [index: number]: number; }'. -!!! error TS2322: Index signature is missing in type 'interfaceWithPublicAndOptional'. \ No newline at end of file +!!! error TS2322: Index signature for type 'number' is missing in type 'interfaceWithPublicAndOptional'. \ No newline at end of file diff --git a/tests/baselines/reference/augmentedTypeAssignmentCompatIndexSignature.errors.txt b/tests/baselines/reference/augmentedTypeAssignmentCompatIndexSignature.errors.txt index e99cac7968cf8..18d295e5caa09 100644 --- a/tests/baselines/reference/augmentedTypeAssignmentCompatIndexSignature.errors.txt +++ b/tests/baselines/reference/augmentedTypeAssignmentCompatIndexSignature.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/types/members/augmentedTypeAssignmentCompatIndexSignature.ts(19,5): error TS2322: Type '() => void' is not assignable to type '{ [n: number]: Bar; }'. - Index signature is missing in type '() => void'. + Index signature for type 'number' is missing in type '() => void'. ==== tests/cases/conformance/types/members/augmentedTypeAssignmentCompatIndexSignature.ts (1 errors) ==== @@ -24,6 +24,6 @@ tests/cases/conformance/types/members/augmentedTypeAssignmentCompatIndexSignatur var v2: { ~~ !!! error TS2322: Type '() => void' is not assignable to type '{ [n: number]: Bar; }'. -!!! error TS2322: Index signature is missing in type '() => void'. +!!! error TS2322: Index signature for type 'number' is missing in type '() => void'. [n: number]: Bar } = f; // Should be allowed \ No newline at end of file diff --git a/tests/baselines/reference/declareClassInterfaceImplementation.errors.txt b/tests/baselines/reference/declareClassInterfaceImplementation.errors.txt index d6944e0e033f6..c93f29db5a50e 100644 --- a/tests/baselines/reference/declareClassInterfaceImplementation.errors.txt +++ b/tests/baselines/reference/declareClassInterfaceImplementation.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/declareClassInterfaceImplementation.ts(5,15): error TS2420: Class 'Buffer' incorrectly implements interface 'IBuffer'. - Index signature is missing in type 'Buffer'. + Index signature for type 'number' is missing in type 'Buffer'. ==== tests/cases/compiler/declareClassInterfaceImplementation.ts (1 errors) ==== @@ -10,7 +10,7 @@ tests/cases/compiler/declareClassInterfaceImplementation.ts(5,15): error TS2420: declare class Buffer implements IBuffer { ~~~~~~ !!! error TS2420: Class 'Buffer' incorrectly implements interface 'IBuffer'. -!!! error TS2420: Index signature is missing in type 'Buffer'. +!!! error TS2420: Index signature for type 'number' is missing in type 'Buffer'. } \ No newline at end of file diff --git a/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=false).errors.txt b/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=false).errors.txt index c37fde9ead1e6..dbf2a1d57a81a 100644 --- a/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=false).errors.txt +++ b/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=false).errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/functionAssignabilityWithArrayLike01.ts(2,7): error TS2322: Type '() => void' is not assignable to type 'ArrayLike'. - Index signature is missing in type '() => void'. + Index signature for type 'number' is missing in type '() => void'. ==== tests/cases/compiler/functionAssignabilityWithArrayLike01.ts (1 errors) ==== @@ -7,4 +7,4 @@ tests/cases/compiler/functionAssignabilityWithArrayLike01.ts(2,7): error TS2322: const array: ArrayLike = func; ~~~~~ !!! error TS2322: Type '() => void' is not assignable to type 'ArrayLike'. -!!! error TS2322: Index signature is missing in type '() => void'. \ No newline at end of file +!!! error TS2322: Index signature for type 'number' is missing in type '() => void'. \ No newline at end of file diff --git a/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=true).errors.txt b/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=true).errors.txt index c37fde9ead1e6..dbf2a1d57a81a 100644 --- a/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=true).errors.txt +++ b/tests/baselines/reference/functionAssignabilityWithArrayLike01(strict=true).errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/functionAssignabilityWithArrayLike01.ts(2,7): error TS2322: Type '() => void' is not assignable to type 'ArrayLike'. - Index signature is missing in type '() => void'. + Index signature for type 'number' is missing in type '() => void'. ==== tests/cases/compiler/functionAssignabilityWithArrayLike01.ts (1 errors) ==== @@ -7,4 +7,4 @@ tests/cases/compiler/functionAssignabilityWithArrayLike01.ts(2,7): error TS2322: const array: ArrayLike = func; ~~~~~ !!! error TS2322: Type '() => void' is not assignable to type 'ArrayLike'. -!!! error TS2322: Index signature is missing in type '() => void'. \ No newline at end of file +!!! error TS2322: Index signature for type 'number' is missing in type '() => void'. \ No newline at end of file diff --git a/tests/baselines/reference/indexSignatureOfTypeUnknownStillRequiresIndexSignature.errors.txt b/tests/baselines/reference/indexSignatureOfTypeUnknownStillRequiresIndexSignature.errors.txt index bcc9d9a05b8b8..2f0186d77876f 100644 --- a/tests/baselines/reference/indexSignatureOfTypeUnknownStillRequiresIndexSignature.errors.txt +++ b/tests/baselines/reference/indexSignatureOfTypeUnknownStillRequiresIndexSignature.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/indexSignatureOfTypeUnknownStillRequiresIndexSignature.ts(9,3): error TS2345: Argument of type '{ name: string; age: number; }[]' is not assignable to parameter of type '{ [x: string]: unknown; }'. - Index signature is missing in type '{ name: string; age: number; }[]'. + Index signature for type 'string' is missing in type '{ name: string; age: number; }[]'. ==== tests/cases/compiler/indexSignatureOfTypeUnknownStillRequiresIndexSignature.ts (1 errors) ==== @@ -14,5 +14,5 @@ tests/cases/compiler/indexSignatureOfTypeUnknownStillRequiresIndexSignature.ts(9 f(stooges); // Should throw ~~~~~~~ !!! error TS2345: Argument of type '{ name: string; age: number; }[]' is not assignable to parameter of type '{ [x: string]: unknown; }'. -!!! error TS2345: Index signature is missing in type '{ name: string; age: number; }[]'. +!!! error TS2345: Index signature for type 'string' is missing in type '{ name: string; age: number; }[]'. \ No newline at end of file diff --git a/tests/baselines/reference/indexSignatureTypeInference.errors.txt b/tests/baselines/reference/indexSignatureTypeInference.errors.txt index 148e583bc6038..27df222364371 100644 --- a/tests/baselines/reference/indexSignatureTypeInference.errors.txt +++ b/tests/baselines/reference/indexSignatureTypeInference.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/types/typeRelationships/typeInference/indexSignatureTypeInference.ts(18,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'v1' must be of type 'Function[]', but here has type 'unknown[]'. tests/cases/conformance/types/typeRelationships/typeInference/indexSignatureTypeInference.ts(18,27): error TS2345: Argument of type 'NumberMap' is not assignable to parameter of type 'StringMap'. - Index signature is missing in type 'NumberMap'. + Index signature for type 'string' is missing in type 'NumberMap'. ==== tests/cases/conformance/types/typeRelationships/typeInference/indexSignatureTypeInference.ts (2 errors) ==== @@ -27,6 +27,6 @@ tests/cases/conformance/types/typeRelationships/typeInference/indexSignatureType !!! related TS6203 tests/cases/conformance/types/typeRelationships/typeInference/indexSignatureTypeInference.ts:15:5: 'v1' was also declared here. ~~~~~~~~~ !!! error TS2345: Argument of type 'NumberMap' is not assignable to parameter of type 'StringMap'. -!!! error TS2345: Index signature is missing in type 'NumberMap'. +!!! error TS2345: Index signature for type 'string' is missing in type 'NumberMap'. var v1 = stringMapToArray(stringMap); // Ok \ No newline at end of file diff --git a/tests/baselines/reference/jsdocImplements_signatures.errors.txt b/tests/baselines/reference/jsdocImplements_signatures.errors.txt index 05760b4aadc0b..1ababbc2c294a 100644 --- a/tests/baselines/reference/jsdocImplements_signatures.errors.txt +++ b/tests/baselines/reference/jsdocImplements_signatures.errors.txt @@ -1,5 +1,5 @@ /a.js(2,7): error TS2420: Class 'B' incorrectly implements interface 'Sig'. - Index signature is missing in type 'B'. + Index signature for type 'string' is missing in type 'B'. ==== /defs.d.ts (0 errors) ==== @@ -11,6 +11,6 @@ class B { ~ !!! error TS2420: Class 'B' incorrectly implements interface 'Sig'. -!!! error TS2420: Index signature is missing in type 'B'. +!!! error TS2420: Index signature for type 'string' is missing in type 'B'. } \ No newline at end of file diff --git a/tests/baselines/reference/objectTypeWithStringAndNumberIndexSignatureToAny.errors.txt b/tests/baselines/reference/objectTypeWithStringAndNumberIndexSignatureToAny.errors.txt index 20362a25942c1..24d5658ceebd0 100644 --- a/tests/baselines/reference/objectTypeWithStringAndNumberIndexSignatureToAny.errors.txt +++ b/tests/baselines/reference/objectTypeWithStringAndNumberIndexSignatureToAny.errors.txt @@ -1,19 +1,19 @@ tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(43,5): error TS2322: Type 'Obj' is not assignable to type 'NumberTo'. - Index signature is missing in type 'Obj'. + Index signature for type 'number' is missing in type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(49,5): error TS2739: Type 'StringTo' is missing the following properties from type 'Obj': hello, world tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(50,5): error TS2739: Type 'NumberTo' is missing the following properties from type 'Obj': hello, world tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(51,5): error TS2739: Type 'StringAndNumberTo' is missing the following properties from type 'Obj': hello, world tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(61,5): error TS2322: Type 'Obj' is not assignable to type 'NumberTo'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(65,5): error TS2322: Type 'Obj' is not assignable to type 'StringTo & NumberTo'. Type 'Obj' is not assignable to type 'NumberTo'. - Index signature is missing in type 'Obj'. + Index signature for type 'number' is missing in type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(67,5): error TS2322: Type 'StringTo' is not assignable to type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(68,5): error TS2322: Type 'NumberTo' is not assignable to type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(69,5): error TS2739: Type 'StringTo & NumberTo' is missing the following properties from type 'Obj': hello, world tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(84,5): error TS2322: Type 'Obj' is not assignable to type 'NumberToNumber'. - Index signature is missing in type 'Obj'. + Index signature for type 'number' is missing in type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(88,5): error TS2322: Type 'Obj' is not assignable to type 'StringToAnyNumberToNumber'. - Index signature is missing in type 'Obj'. + Index signature for type 'number' is missing in type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(90,5): error TS2322: Type 'StringTo' is not assignable to type 'Obj'. tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatureToAny.ts(91,5): error TS2739: Type 'NumberTo' is missing the following properties from type 'Obj': hello, world @@ -64,7 +64,7 @@ tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatur nToAny = someObj; ~~~~~~ !!! error TS2322: Type 'Obj' is not assignable to type 'NumberTo'. -!!! error TS2322: Index signature is missing in type 'Obj'. +!!! error TS2322: Index signature for type 'number' is missing in type 'Obj'. bothToAny = sToAny; bothToAny = nToAny; @@ -98,7 +98,7 @@ tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatur ~~~~~~~~~ !!! error TS2322: Type 'Obj' is not assignable to type 'StringTo & NumberTo'. !!! error TS2322: Type 'Obj' is not assignable to type 'NumberTo'. -!!! error TS2322: Index signature is missing in type 'Obj'. +!!! error TS2322: Index signature for type 'number' is missing in type 'Obj'. someObj = sToAny; ~~~~~~~ @@ -126,14 +126,14 @@ tests/cases/conformance/types/members/objectTypeWithStringAndNumberIndexSignatur nToNumber = someObj; ~~~~~~~~~ !!! error TS2322: Type 'Obj' is not assignable to type 'NumberToNumber'. -!!! error TS2322: Index signature is missing in type 'Obj'. +!!! error TS2322: Index signature for type 'number' is missing in type 'Obj'. strToAnyNumToNum = sToAny; strToAnyNumToNum = nToNumber; strToAnyNumToNum = someObj; ~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'Obj' is not assignable to type 'StringToAnyNumberToNumber'. -!!! error TS2322: Index signature is missing in type 'Obj'. +!!! error TS2322: Index signature for type 'number' is missing in type 'Obj'. someObj = sToAny; ~~~~~~~ diff --git a/tests/baselines/reference/parseTypes.errors.txt b/tests/baselines/reference/parseTypes.errors.txt index aca1ddff31355..8548cedc373d4 100644 --- a/tests/baselines/reference/parseTypes.errors.txt +++ b/tests/baselines/reference/parseTypes.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/parseTypes.ts(8,1): error TS2322: Type '(s: string) => void' is not assignable to type '() => number'. tests/cases/compiler/parseTypes.ts(9,1): error TS2322: Type '(s: string) => void' is not assignable to type '() => number'. tests/cases/compiler/parseTypes.ts(10,1): error TS2322: Type '(s: string) => void' is not assignable to type '{ [x: number]: number; }'. - Index signature is missing in type '(s: string) => void'. + Index signature for type 'number' is missing in type '(s: string) => void'. tests/cases/compiler/parseTypes.ts(11,1): error TS2322: Type '(s: string) => void' is not assignable to type 'new () => number'. Type '(s: string) => void' provides no match for the signature 'new (): number'. @@ -23,7 +23,7 @@ tests/cases/compiler/parseTypes.ts(11,1): error TS2322: Type '(s: string) => voi w=g; ~ !!! error TS2322: Type '(s: string) => void' is not assignable to type '{ [x: number]: number; }'. -!!! error TS2322: Index signature is missing in type '(s: string) => void'. +!!! error TS2322: Index signature for type 'number' is missing in type '(s: string) => void'. z=g; ~ !!! error TS2322: Type '(s: string) => void' is not assignable to type 'new () => number'. diff --git a/tests/baselines/reference/stringIndexerAssignments2.errors.txt b/tests/baselines/reference/stringIndexerAssignments2.errors.txt index 256a9820a0c44..b4fa8b8485501 100644 --- a/tests/baselines/reference/stringIndexerAssignments2.errors.txt +++ b/tests/baselines/reference/stringIndexerAssignments2.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/stringIndexerAssignments2.ts(19,1): error TS2322: Type 'C2' is not assignable to type 'C1'. - Index signature is missing in type 'C2'. + Index signature for type 'string' is missing in type 'C2'. tests/cases/compiler/stringIndexerAssignments2.ts(20,1): error TS2322: Type 'C3' is not assignable to type 'C1'. Types of property 'one' are incompatible. Type 'number' is not assignable to type 'string'. @@ -27,7 +27,7 @@ tests/cases/compiler/stringIndexerAssignments2.ts(20,1): error TS2322: Type 'C3' x = a; ~ !!! error TS2322: Type 'C2' is not assignable to type 'C1'. -!!! error TS2322: Index signature is missing in type 'C2'. +!!! error TS2322: Index signature for type 'string' is missing in type 'C2'. x = b; ~ !!! error TS2322: Type 'C3' is not assignable to type 'C1'. diff --git a/tests/baselines/reference/subclassThisTypeAssignable01.errors.txt b/tests/baselines/reference/subclassThisTypeAssignable01.errors.txt index d8bce35304add..be9404bf1fd7d 100644 --- a/tests/baselines/reference/subclassThisTypeAssignable01.errors.txt +++ b/tests/baselines/reference/subclassThisTypeAssignable01.errors.txt @@ -8,9 +8,9 @@ tests/cases/compiler/tile1.ts(21,2): error TS2416: Property 'view' in type 'C' i Type 'Vnode' is not assignable to type 'Vnode>'. Type 'this' is not assignable to type 'Lifecycle'. Type 'C' is not assignable to type 'Lifecycle'. - Index signature is missing in type 'C'. + Index signature for type 'number' is missing in type 'C'. tests/cases/compiler/tile1.ts(24,7): error TS2322: Type 'C' is not assignable to type 'ClassComponent'. - Index signature is missing in type 'C'. + Index signature for type 'number' is missing in type 'C'. ==== tests/cases/compiler/tile1.ts (5 errors) ==== @@ -48,13 +48,13 @@ tests/cases/compiler/tile1.ts(24,7): error TS2322: Type 'C' is not assignable to !!! error TS2416: Type 'Vnode' is not assignable to type 'Vnode>'. !!! error TS2416: Type 'this' is not assignable to type 'Lifecycle'. !!! error TS2416: Type 'C' is not assignable to type 'Lifecycle'. -!!! error TS2416: Index signature is missing in type 'C'. +!!! error TS2416: Index signature for type 'number' is missing in type 'C'. } const test8: ClassComponent = new C(); ~~~~~ !!! error TS2322: Type 'C' is not assignable to type 'ClassComponent'. -!!! error TS2322: Index signature is missing in type 'C'. +!!! error TS2322: Index signature for type 'number' is missing in type 'C'. ==== tests/cases/compiler/file1.js (1 errors) ==== /** @type {ClassComponent} */ const test9 = new C(); diff --git a/tests/baselines/reference/underscoreTest1.errors.txt b/tests/baselines/reference/underscoreTest1.errors.txt index 7bc8e28cf08ec..4fe89d1139b01 100644 --- a/tests/baselines/reference/underscoreTest1.errors.txt +++ b/tests/baselines/reference/underscoreTest1.errors.txt @@ -5,7 +5,7 @@ tests/cases/compiler/underscoreTest1_underscoreTests.ts(26,1): error TS2769: No Type 'string' is not assignable to type 'boolean'. Overload 2 of 2, '(list: Dictionary, iterator?: Iterator_, context?: any): boolean', gave the following error. Argument of type '(string | number | boolean)[]' is not assignable to parameter of type 'Dictionary'. - Index signature is missing in type '(string | number | boolean)[]'. + Index signature for type 'string' is missing in type '(string | number | boolean)[]'. ==== tests/cases/compiler/underscoreTest1_underscoreTests.ts (1 errors) ==== @@ -43,7 +43,7 @@ tests/cases/compiler/underscoreTest1_underscoreTests.ts(26,1): error TS2769: No !!! error TS2769: Type 'string' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(list: Dictionary, iterator?: Iterator_, context?: any): boolean', gave the following error. !!! error TS2769: Argument of type '(string | number | boolean)[]' is not assignable to parameter of type 'Dictionary'. -!!! error TS2769: Index signature is missing in type '(string | number | boolean)[]'. +!!! error TS2769: Index signature for type 'string' is missing in type '(string | number | boolean)[]'. _.any([null, 0, 'yes', false]); diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index 60856e8ce182b..e2f3126329ecf 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -19,7 +19,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(114,9): error TS2322: Type tests/cases/conformance/types/unknown/unknownType1.ts(120,9): error TS2322: Type 'T' is not assignable to type 'object'. Type 'unknown' is not assignable to type 'object'. tests/cases/conformance/types/unknown/unknownType1.ts(128,5): error TS2322: Type 'number[]' is not assignable to type '{ [x: string]: unknown; }'. - Index signature is missing in type 'number[]'. + Index signature for type 'string' is missing in type 'number[]'. tests/cases/conformance/types/unknown/unknownType1.ts(129,5): error TS2322: Type 'number' is not assignable to type '{ [x: string]: unknown; }'. tests/cases/conformance/types/unknown/unknownType1.ts(143,29): error TS2698: Spread types may only be created from object types. tests/cases/conformance/types/unknown/unknownType1.ts(144,29): error TS2698: Spread types may only be created from object types. @@ -201,7 +201,7 @@ tests/cases/conformance/types/unknown/unknownType1.ts(181,5): error TS2322: Type x = [1, 2, 3]; // Error ~ !!! error TS2322: Type 'number[]' is not assignable to type '{ [x: string]: unknown; }'. -!!! error TS2322: Index signature is missing in type 'number[]'. +!!! error TS2322: Index signature for type 'string' is missing in type 'number[]'. x = 123; // Error ~ !!! error TS2322: Type 'number' is not assignable to type '{ [x: string]: unknown; }'. From 61297e35bdb4715ac447da679ce01e3c0cd944c5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 5 Jun 2021 11:14:55 -0700 Subject: [PATCH 18/56] Make 'number' index signatures consistently apply to numeric strings --- src/compiler/checker.ts | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0136173c1a84e..700cb91465c15 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12021,16 +12021,23 @@ namespace ts { return undefined; } + function isApplicableIndexType(source: Type, target: Type) { + // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index + // signature applies to types assignable to 'number' or `${number}`. + return isTypeAssignableTo(source, target) || + target === stringType && isTypeAssignableTo(source, numberType) || + target === numberType && source.flags & TypeFlags.StringLiteral && isNumericLiteralName((source as StringLiteralType).value); + } + function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { - const indexInfos = getIndexInfosOfType(type); let stringIndexInfo: IndexInfo | undefined; let applicableInfo: IndexInfo | undefined; let applicableInfos: IndexInfo[] | undefined; - for (const info of indexInfos) { + for (const info of getIndexInfosOfType(type)) { if (info.keyType === stringType) { stringIndexInfo = info; } - else if (isTypeAssignableTo(keyType, info.keyType)) { + else if (isApplicableIndexType(keyType, info.keyType)) { if (!applicableInfo) { applicableInfo = info; } @@ -12042,14 +12049,15 @@ namespace ts { // When more than one index signature is applicable we create a synthetic IndexInfo. Instead of computing // the intersected key type, we just use unknownType for the key type as nothing actually depends on the // keyType property of the returned IndexInfo. - return applicableInfos ? - createIndexInfo(unknownType, getIntersectionType(map(applicableInfos, info => info.type)), + return applicableInfos ? createIndexInfo(unknownType, getIntersectionType(map(applicableInfos, info => info.type)), reduceLeft(applicableInfos, (isReadonly, info) => isReadonly && info.isReadonly, /*initial*/ true)) : - applicableInfo || stringIndexInfo; + applicableInfo ? applicableInfo : + stringIndexInfo && isApplicableIndexType(keyType, stringType) ? stringIndexInfo : + undefined; } function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined { - return isNumericLiteralName(name) && getIndexInfoOfType(type, numberType) || getApplicableIndexInfo(type, getLiteralType(unescapeLeadingUnderscores(name))); + return getApplicableIndexInfo(type, getLiteralType(unescapeLeadingUnderscores(name))); } // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual @@ -14668,7 +14676,9 @@ namespace ts { if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { return objectType; } - const indexInfo = getApplicableIndexInfo(objectType, indexType); + // If no index signature is applicable, we default to the string index signature. In effect, this means the string + // index signature applies even when accessing with a symbol-like type. + const indexInfo = getApplicableIndexInfo(objectType, indexType) || getIndexInfoOfType(objectType, stringType); if (indexInfo) { if (accessFlags & AccessFlags.NoIndexSignatures && indexInfo.keyType !== numberType) { if (accessExpression) { From 7f0f4c3b37cbc7f98bc048416e38d84bcb28962b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 5 Jun 2021 11:15:19 -0700 Subject: [PATCH 19/56] Accept new baselines --- tests/baselines/reference/bigintIndex.types | 6 ++-- ...ricCallWithObjectTypeArgsAndIndexers.types | 4 +-- ...lWithObjectTypeArgsAndIndexersErrors.types | 4 +-- .../mergedInterfacesWithIndexers.types | 4 +-- .../reference/numericIndexingResults.types | 28 +++++++++---------- .../baselines/reference/objectRest.errors.txt | 8 +----- tests/baselines/reference/objectRest.types | 4 +-- .../templateStringInIndexExpression.types | 2 +- .../templateStringInIndexExpressionES6.types | 2 +- 9 files changed, 28 insertions(+), 34 deletions(-) diff --git a/tests/baselines/reference/bigintIndex.types b/tests/baselines/reference/bigintIndex.types index a70c1f9aec573..1d80ce04fe707 100644 --- a/tests/baselines/reference/bigintIndex.types +++ b/tests/baselines/reference/bigintIndex.types @@ -18,9 +18,9 @@ let num: number = arr[1]; >1 : 1 num = arr["1"]; ->num = arr["1"] : any +>num = arr["1"] : number >num : number ->arr["1"] : any +>arr["1"] : number >arr : number[] >"1" : "1" @@ -84,7 +84,7 @@ typedArray[String(bigNum)] = 0xAA; typedArray["1"] = 0xBB; >typedArray["1"] = 0xBB : 187 ->typedArray["1"] : any +>typedArray["1"] : number >typedArray : Uint8Array >"1" : "1" >0xBB : 187 diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexers.types b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexers.types index 64b15afb8f155..fb9eed9d9a1b6 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexers.types +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexers.types @@ -52,8 +52,8 @@ function other(arg: T) { >1 : 1 var e = r2['1']; ->e : Object ->r2['1'] : Object +>e : T +>r2['1'] : T >r2 : { [x: string]: Object; [x: number]: T; } >'1' : "1" } diff --git a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.types b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.types index 1e9b5d82c634e..7006fe613e109 100644 --- a/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.types +++ b/tests/baselines/reference/genericCallWithObjectTypeArgsAndIndexersErrors.types @@ -57,8 +57,8 @@ function other3(arg: T) { >1 : 1 var e = r2['1']; ->e : Object ->r2['1'] : Object +>e : T +>r2['1'] : T >r2 : { [x: string]: Object; [x: number]: T; } >'1' : "1" diff --git a/tests/baselines/reference/mergedInterfacesWithIndexers.types b/tests/baselines/reference/mergedInterfacesWithIndexers.types index 73e0ee72c941b..1154fcd72ef1d 100644 --- a/tests/baselines/reference/mergedInterfacesWithIndexers.types +++ b/tests/baselines/reference/mergedInterfacesWithIndexers.types @@ -23,8 +23,8 @@ var r = a[1]; >1 : 1 var r2 = a['1']; ->r2 : { length: number; } ->a['1'] : { length: number; } +>r2 : string +>a['1'] : string >a : A >'1' : "1" diff --git a/tests/baselines/reference/numericIndexingResults.types b/tests/baselines/reference/numericIndexingResults.types index f4e0d168e6e22..78f47edbe489c 100644 --- a/tests/baselines/reference/numericIndexingResults.types +++ b/tests/baselines/reference/numericIndexingResults.types @@ -30,8 +30,8 @@ var r2 = c['2']; >'2' : "2" var r3 = c['3']; ->r3 : error ->c['3'] : error +>r3 : string +>c['3'] : string >c : C >'3' : "3" @@ -80,8 +80,8 @@ var r2 = i['2']; >'2' : "2" var r3 = i['3']; ->r3 : error ->i['3'] : error +>r3 : string +>i['3'] : string >i : I >'3' : "3" @@ -129,8 +129,8 @@ var r2 = a['2']; >'2' : "2" var r3 = a['3']; ->r3 : error ->a['3'] : error +>r3 : string +>a['3'] : string >a : { [x: number]: string; 1: string; "2": string; } >'3' : "3" @@ -162,20 +162,20 @@ var b: { [x: number]: string } = { 1: '', "2": '' } >'' : "" var r1a = b['1']; ->r1a : error ->b['1'] : error +>r1a : string +>b['1'] : string >b : { [x: number]: string; } >'1' : "1" var r2a = b['2']; ->r2a : error ->b['2'] : error +>r2a : string +>b['2'] : string >b : { [x: number]: string; } >'2' : "2" var r3 = b['3']; ->r3 : error ->b['3'] : error +>r3 : string +>b['3'] : string >b : { [x: number]: string; } >'3' : "3" @@ -221,8 +221,8 @@ var r2b = b2['2']; >'2' : "2" var r3 = b2['3']; ->r3 : error ->b2['3'] : error +>r3 : string +>b2['3'] : string >b2 : { [x: number]: string; 1: string; "2": string; } >'3' : "3" diff --git a/tests/baselines/reference/objectRest.errors.txt b/tests/baselines/reference/objectRest.errors.txt index f6fd179d28d3a..50561ae18cab4 100644 --- a/tests/baselines/reference/objectRest.errors.txt +++ b/tests/baselines/reference/objectRest.errors.txt @@ -1,5 +1,3 @@ -tests/cases/conformance/types/rest/objectRest.ts(7,12): error TS2339: Property '0' does not exist on type 'String'. -tests/cases/conformance/types/rest/objectRest.ts(7,20): error TS2339: Property '1' does not exist on type 'String'. tests/cases/conformance/types/rest/objectRest.ts(43,8): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. tests/cases/conformance/types/rest/objectRest.ts(43,35): error TS2537: Type '{ a: number; b: string; }' has no matching index signature for type 'string'. tests/cases/conformance/types/rest/objectRest.ts(43,57): error TS2403: Subsequent variable declarations must have the same type. Variable 'o' must be of type '{ a: number; b: string; }', but here has type '{}'. @@ -8,7 +6,7 @@ tests/cases/conformance/types/rest/objectRest.ts(44,32): error TS2537: Type '{ a tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2739: Type '{}' is missing the following properties from type '{ a: number; b: string; }': a, b -==== tests/cases/conformance/types/rest/objectRest.ts (8 errors) ==== +==== tests/cases/conformance/types/rest/objectRest.ts (6 errors) ==== var o = { a: 1, b: 'no' } var { ...clone } = o; var { a, ...justB } = o; @@ -16,10 +14,6 @@ tests/cases/conformance/types/rest/objectRest.ts(44,53): error TS2739: Type '{}' var { ['b']: renamed, ...justA } = o; var { 'b': renamed, ...justA } = o; var { b: { '0': n, '1': oooo }, ...justA } = o; - ~~~ -!!! error TS2339: Property '0' does not exist on type 'String'. - ~~~ -!!! error TS2339: Property '1' does not exist on type 'String'. let o2 = { c: 'terrible idea?', d: 'yes' }; var { d: renamed, ...d } = o2; diff --git a/tests/baselines/reference/objectRest.types b/tests/baselines/reference/objectRest.types index b0d34beae7dac..821bb809972dd 100644 --- a/tests/baselines/reference/objectRest.types +++ b/tests/baselines/reference/objectRest.types @@ -36,8 +36,8 @@ var { 'b': renamed, ...justA } = o; var { b: { '0': n, '1': oooo }, ...justA } = o; >b : any ->n : any ->oooo : any +>n : string +>oooo : string >justA : { a: number; } >o : { a: number; b: string; } diff --git a/tests/baselines/reference/templateStringInIndexExpression.types b/tests/baselines/reference/templateStringInIndexExpression.types index 9ad6b1e141db0..2e38c933e6e93 100644 --- a/tests/baselines/reference/templateStringInIndexExpression.types +++ b/tests/baselines/reference/templateStringInIndexExpression.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/templates/templateStringInIndexExpression.ts === `abc${0}abc`[`0`]; ->`abc${0}abc`[`0`] : error +>`abc${0}abc`[`0`] : string >`abc${0}abc` : string >0 : 0 >`0` : "0" diff --git a/tests/baselines/reference/templateStringInIndexExpressionES6.types b/tests/baselines/reference/templateStringInIndexExpressionES6.types index d86fb2309e72b..389d3367a3e62 100644 --- a/tests/baselines/reference/templateStringInIndexExpressionES6.types +++ b/tests/baselines/reference/templateStringInIndexExpressionES6.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/templates/templateStringInIndexExpressionES6.ts === `abc${0}abc`[`0`]; ->`abc${0}abc`[`0`] : error +>`abc${0}abc`[`0`] : string >`abc${0}abc` : string >0 : 0 >`0` : "0" From 9442790170ff4cfba734de749615c554e550e608 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 5 Jun 2021 11:16:06 -0700 Subject: [PATCH 20/56] Update fourslash test --- tests/cases/fourslash/indexerReturnTypes1.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/cases/fourslash/indexerReturnTypes1.ts b/tests/cases/fourslash/indexerReturnTypes1.ts index cb38a79598eac..23b0192f87f10 100644 --- a/tests/cases/fourslash/indexerReturnTypes1.ts +++ b/tests/cases/fourslash/indexerReturnTypes1.ts @@ -63,19 +63,19 @@ verify.quickInfos({ 1: "var r1: Date", - 2: "var r2: any", + 2: "var r2: Date", 3: "var r3: RegExp", 4: "var r4: RegExp", 5: "var r5: Date", - 6: "var r6: any", + 6: "var r6: Date", 7: "var r7: RegExp", 8: "var r8: RegExp", 9: "var r9: Date", - 10: "var r10: any", + 10: "var r10: Date", 11: "var r11: Date", 12: "var r12: Date", 13: "var r13: Ty", - 14: "var r14: any", + 14: "var r14: Ty", 15: "var r15: {\n [x: number]: Date;\n}", - 16: "var r16: any" + 16: "var r16: {\n [x: number]: Date;\n}" }); From f96f5138049124160625a1da446c1bb5945f705f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Jun 2021 08:01:23 -0700 Subject: [PATCH 21/56] Revise index constraint checking --- src/compiler/checker.ts | 159 +++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 92 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 700cb91465c15..052cb2c81eb58 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12023,12 +12023,16 @@ namespace ts { function isApplicableIndexType(source: Type, target: Type) { // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index - // signature applies to types assignable to 'number' or `${number}`. + // signature applies to types assignable to 'number' and numeric string literal types. return isTypeAssignableTo(source, target) || target === stringType && isTypeAssignableTo(source, numberType) || target === numberType && source.flags & TypeFlags.StringLiteral && isNumericLiteralName((source as StringLiteralType).value); } + function getApplicableIndexInfos(type: Type, keyType: Type): IndexInfo[] { + return getIndexInfosOfType(type).filter(info => isApplicableIndexType(keyType, info.keyType)); + } + function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { let stringIndexInfo: IndexInfo | undefined; let applicableInfo: IndexInfo | undefined; @@ -14369,8 +14373,8 @@ namespace ts { }); } - function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags) { - if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { + function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags, includeNonPublic?: boolean) { + if (includeNonPublic || !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { let type = getSymbolLinks(getLateBoundSymbol(prop)).nameType; if (!type) { if (prop.escapedName === InternalSymbolName.Default) { @@ -36854,105 +36858,76 @@ namespace ts { } function checkIndexConstraints(type: Type, isStatic?: boolean) { - const symbolTable = isStatic ? type.symbol?.exports : type.symbol?.members; - const indexSymbol = symbolTable && getIndexSymbolFromSymbolTable(symbolTable); - const indexInfos = indexSymbol ? getIndexInfosOfIndexSymbol(indexSymbol) : emptyArray; - const declaredStringIndexer = findIndexInfo(indexInfos, stringType)?.declaration; - const declaredNumberIndexer = findIndexInfo(indexInfos, numberType)?.declaration; - - const stringIndexType = getIndexTypeOfType(type, stringType); - const numberIndexType = getIndexTypeOfType(type, numberType); - - if (stringIndexType || numberIndexType) { - forEach(getPropertiesOfObjectType(type), prop => { - if (isStatic && prop.flags & SymbolFlags.Prototype) return; - const propType = getTypeOfSymbol(prop); - checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, stringType); - checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, numberType); - }); - - const classDeclaration = type.symbol.valueDeclaration; - if (getObjectFlags(type) & ObjectFlags.Class && classDeclaration && isClassLike(classDeclaration)) { - for (const member of classDeclaration.members) { - // Only process instance properties with computed names here. - // Static properties cannot be in conflict with indexers, - // and properties with literal names were already checked. - if (!hasSyntacticModifier(member, ModifierFlags.Static) && !hasBindableName(member)) { - const symbol = getSymbolOfNode(member); - const propType = getTypeOfSymbol(symbol); - checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, stringType); - checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, numberType); - } + const indexInfos = getIndexInfosOfType(type); + if (indexInfos.length === 0) { + return; + } + for (const prop of getPropertiesOfObjectType(type)) { + if (!(isStatic && prop.flags & SymbolFlags.Prototype)) { + checkIndexConstraintForProperty(type, prop, getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique, /*includeNonPublic*/ true), getTypeOfSymbol(prop)); + } + } + const typeDeclaration = type.symbol.valueDeclaration; + if (typeDeclaration && isClassLike(typeDeclaration)) { + for (const member of typeDeclaration.members) { + // Only process instance properties with computed names here. Static properties cannot be in conflict with indexers, + // and properties with literal names were already checked. + if (!hasSyntacticModifier(member, ModifierFlags.Static) && !hasBindableName(member)) { + const symbol = getSymbolOfNode(member); + checkIndexConstraintForProperty(type, symbol, getTypeOfExpression((member as DynamicNamedDeclaration).name.expression), getTypeOfSymbol(symbol)); } } } - - let errorNode: Node | undefined; - if (stringIndexType && numberIndexType) { - errorNode = declaredNumberIndexer || declaredStringIndexer; - // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer - if (!errorNode && (getObjectFlags(type) & ObjectFlags.Interface)) { - const someBaseTypeHasBothIndexers = forEach(getBaseTypes(type as InterfaceType), base => getIndexTypeOfType(base, stringType) && getIndexTypeOfType(base, numberType)); - errorNode = someBaseTypeHasBothIndexers || !type.symbol.declarations ? undefined : type.symbol.declarations[0]; + if (indexInfos.length > 1) { + for (const info of indexInfos) { + checkIndexConstraintForIndexSignature(type, info); } } + } - if (errorNode && !isTypeAssignableTo(numberIndexType!, stringIndexType!)) { // TODO: GH#18217 - error(errorNode, Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, - typeToString(numberIndexType!), typeToString(stringIndexType!)); + function checkIndexConstraintForProperty(type: Type, prop: Symbol, propNameType: Type, propType: Type) { + const declaration = prop.valueDeclaration; + const name = getNameOfDeclaration(declaration); + if (name && isPrivateIdentifier(name)) { + return; } - - function checkIndexConstraintForProperty( - prop: Symbol, - propertyType: Type, - containingType: Type, - indexDeclaration: Declaration | undefined, - indexType: Type | undefined, - keyType: Type): void { - - // ESSymbol properties apply to neither string nor numeric indexers. - if (!indexType || isKnownSymbol(prop)) { - return; - } - - const propDeclaration = prop.valueDeclaration; - const name = propDeclaration && getNameOfDeclaration(propDeclaration); - - if (name && isPrivateIdentifier(name)) { - return; - } - - // index is numeric and property name is not valid numeric literal - if (keyType === numberType && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) { - return; - } - - // perform property check if property or indexer is declared in 'type' - // this allows us to rule out cases when both property and indexer are inherited from the base class - let errorNode: Node | undefined; - if (propDeclaration && name && - (propDeclaration.kind === SyntaxKind.BinaryExpression || - name.kind === SyntaxKind.ComputedPropertyName || - prop.parent === containingType.symbol)) { - errorNode = propDeclaration; - } - else if (indexDeclaration) { - errorNode = indexDeclaration; - } - else if (getObjectFlags(containingType) & ObjectFlags.Interface) { - // for interfaces property and indexer might be inherited from different bases - // check if any base class already has both property and indexer. - // check should be performed only if 'type' is the first type that brings property\indexer together - const someBaseClassHasBothPropertyAndIndexer = forEach(getBaseTypes(containingType as InterfaceType), base => getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, keyType)); - errorNode = someBaseClassHasBothPropertyAndIndexer || !containingType.symbol.declarations ? undefined : containingType.symbol.declarations[0]; - } - - if (errorNode && !isTypeAssignableTo(propertyType, indexType)) { + const indexInfos = getApplicableIndexInfos(type, propNameType); + const interfaceDeclaration = getObjectFlags(type) & ObjectFlags.Interface ? getDeclarationOfKind(type.symbol, SyntaxKind.InterfaceDeclaration) : undefined; + const localPropDeclaration = declaration && declaration.kind === SyntaxKind.BinaryExpression || + name && name.kind === SyntaxKind.ComputedPropertyName || getParentOfSymbol(prop) === type.symbol ? declaration : undefined; + for (const info of indexInfos) { + const localIndexDeclaration = info.declaration && getParentOfSymbol(getSymbolOfNode(info.declaration)) === type.symbol ? info.declaration : undefined; + // We check only when (a) the property is declared in the containing type, or (b) the applicable index signature is declared + // in the containing type, or (c) the containing type is an interface and no base interface contains both the property and + // the index signature (i.e. property and index signature are declared in separate inherited interfaces). + const errorNode = localPropDeclaration || localIndexDeclaration || + (interfaceDeclaration && !some(getBaseTypes(type as InterfaceType), base => !!getPropertyOfObjectType(base, prop.escapedName) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); + if (errorNode && !isTypeAssignableTo(propType, info.type)) { const errorMessage = - keyType === stringType + info.keyType === stringType ? Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2 : Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2; - error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType)); + error(errorNode, errorMessage, symbolToString(prop), typeToString(propType), typeToString(info.type)); + } + } + } + + function checkIndexConstraintForIndexSignature(type: Type, checkInfo: IndexInfo) { + const declaration = checkInfo.declaration; + const indexInfos = getApplicableIndexInfos(type, checkInfo.keyType); + const interfaceDeclaration = getObjectFlags(type) & ObjectFlags.Interface ? getDeclarationOfKind(type.symbol, SyntaxKind.InterfaceDeclaration) : undefined; + const localCheckDeclaration = declaration && getParentOfSymbol(getSymbolOfNode(declaration)) === type.symbol ? declaration : undefined; + for (const info of indexInfos) { + if (info === checkInfo) continue; + const localIndexDeclaration = info.declaration && getParentOfSymbol(getSymbolOfNode(info.declaration)) === type.symbol ? info.declaration : undefined; + // We check only when (a) the check index signature is declared in the containing type, or (b) the applicable index + // signature is declared in the containing type, or (c) the containing type is an interface and no base interface contains + // both index signatures (i.e. the index signatures are declared in separate inherited interfaces). + const errorNode = localCheckDeclaration || localIndexDeclaration || + (interfaceDeclaration && !some(getBaseTypes(type as InterfaceType), base => !!getIndexInfoOfType(base, checkInfo.keyType) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); + if (errorNode && !isTypeAssignableTo(checkInfo.type, info.type)) { + error(errorNode, Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, + typeToString(checkInfo.type), typeToString(info.type)); } } } From 91e35469a2bb3c82a5a3174af00202a174a80a59 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Jun 2021 08:01:39 -0700 Subject: [PATCH 22/56] Accept new baselines --- ...peHidingMembersOfExtendedObject.errors.txt | 36 ++++++------------- ...tringIndexerHidingObjectIndexer.errors.txt | 30 +++++----------- .../reference/symbolProperty17.errors.txt | 14 ++++++++ .../reference/symbolProperty30.errors.txt | 12 +++++++ .../reference/symbolProperty32.errors.txt | 14 ++++++++ .../reference/symbolProperty34.errors.txt | 5 ++- 6 files changed, 63 insertions(+), 48 deletions(-) create mode 100644 tests/baselines/reference/symbolProperty17.errors.txt create mode 100644 tests/baselines/reference/symbolProperty30.errors.txt create mode 100644 tests/baselines/reference/symbolProperty32.errors.txt diff --git a/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt b/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt index 94810f6d0028f..3a2a4ed691f1a 100644 --- a/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt +++ b/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt @@ -1,14 +1,14 @@ -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. +tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(10,5): error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. +lib.es5.d.ts(122,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. +lib.es5.d.ts(125,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. +lib.es5.d.ts(128,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. +lib.es5.d.ts(131,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. +lib.es5.d.ts(137,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. +lib.es5.d.ts(143,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. +lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -==== tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts (8 errors) ==== +==== tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts (1 errors) ==== class A { foo: string; } @@ -19,23 +19,9 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts interface Object { data: A; - [x: string]: Object; - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ + ~~~~ !!! error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. + [x: string]: Object; } class C { diff --git a/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt b/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt index d85cc3ddfdb11..b244bb47413cb 100644 --- a/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt +++ b/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt @@ -1,32 +1,18 @@ -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. +lib.es5.d.ts(122,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. +lib.es5.d.ts(125,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. +lib.es5.d.ts(128,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. +lib.es5.d.ts(131,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. +lib.es5.d.ts(137,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. +lib.es5.d.ts(143,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. +lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -==== tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts (7 errors) ==== +==== tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts (0 errors) ==== // object types can define string indexers that are more specific than the default 'any' that would be returned // no errors expected below interface Object { [x: string]: Object; - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. - ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. } var o = {}; var r = o['']; // should be Object diff --git a/tests/baselines/reference/symbolProperty17.errors.txt b/tests/baselines/reference/symbolProperty17.errors.txt new file mode 100644 index 0000000000000..44e34bb7ec0e1 --- /dev/null +++ b/tests/baselines/reference/symbolProperty17.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/es6/Symbols/symbolProperty17.ts(2,5): error TS2412: Property '[Symbol.iterator]' of type 'number' is not assignable to numeric index type 'string'. + + +==== tests/cases/conformance/es6/Symbols/symbolProperty17.ts (1 errors) ==== + interface I { + [Symbol.iterator]: number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2412: Property '[Symbol.iterator]' of type 'number' is not assignable to numeric index type 'string'. + [s: symbol]: string; + "__@iterator": string; + } + + var i: I; + var it = i[Symbol.iterator]; \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty30.errors.txt b/tests/baselines/reference/symbolProperty30.errors.txt new file mode 100644 index 0000000000000..1993f25412e90 --- /dev/null +++ b/tests/baselines/reference/symbolProperty30.errors.txt @@ -0,0 +1,12 @@ +tests/cases/conformance/es6/Symbols/symbolProperty30.ts(2,5): error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. + + +==== tests/cases/conformance/es6/Symbols/symbolProperty30.ts (1 errors) ==== + class C1 { + [Symbol.toStringTag]() { + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. + return { x: "" }; + } + [s: symbol]: () => { x: number }; + } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty32.errors.txt b/tests/baselines/reference/symbolProperty32.errors.txt new file mode 100644 index 0000000000000..369371df18eb6 --- /dev/null +++ b/tests/baselines/reference/symbolProperty32.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/es6/Symbols/symbolProperty32.ts(2,5): error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. + + +==== tests/cases/conformance/es6/Symbols/symbolProperty32.ts (1 errors) ==== + class C1 { + [Symbol.toStringTag]() { + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. + return { x: "" }; + } + } + class C2 extends C1 { + [s: symbol]: () => { x: number }; + } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty34.errors.txt b/tests/baselines/reference/symbolProperty34.errors.txt index 6adbeb6fa7afb..e7e2c858cd886 100644 --- a/tests/baselines/reference/symbolProperty34.errors.txt +++ b/tests/baselines/reference/symbolProperty34.errors.txt @@ -1,12 +1,15 @@ tests/cases/conformance/es6/Symbols/symbolProperty34.ts(1,18): error TS2449: Class 'C2' used before its declaration. +tests/cases/conformance/es6/Symbols/symbolProperty34.ts(2,5): error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. -==== tests/cases/conformance/es6/Symbols/symbolProperty34.ts (1 errors) ==== +==== tests/cases/conformance/es6/Symbols/symbolProperty34.ts (2 errors) ==== class C1 extends C2 { ~~ !!! error TS2449: Class 'C2' used before its declaration. !!! related TS2728 tests/cases/conformance/es6/Symbols/symbolProperty34.ts:6:7: 'C2' is declared here. [Symbol.toStringTag]() { + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. return { x: "" }; } } From f24a654f8441c507f6b3f5fe918597fe139dedea Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Jun 2021 08:50:37 -0700 Subject: [PATCH 23/56] Update error messages --- src/compiler/checker.ts | 11 ++++------- src/compiler/diagnosticMessages.json | 8 ++------ src/services/codefixes/fixInvalidImportSyntax.ts | 5 ++--- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 052cb2c81eb58..afdf0581221e7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36903,11 +36903,8 @@ namespace ts { const errorNode = localPropDeclaration || localIndexDeclaration || (interfaceDeclaration && !some(getBaseTypes(type as InterfaceType), base => !!getPropertyOfObjectType(base, prop.escapedName) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); if (errorNode && !isTypeAssignableTo(propType, info.type)) { - const errorMessage = - info.keyType === stringType - ? Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2 - : Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2; - error(errorNode, errorMessage, symbolToString(prop), typeToString(propType), typeToString(info.type)); + error(errorNode, Diagnostics.Property_0_of_type_1_is_not_assignable_to_2_index_type_3, + symbolToString(prop), typeToString(propType), typeToString(info.keyType), typeToString(info.type)); } } } @@ -36926,8 +36923,8 @@ namespace ts { const errorNode = localCheckDeclaration || localIndexDeclaration || (interfaceDeclaration && !some(getBaseTypes(type as InterfaceType), base => !!getIndexInfoOfType(base, checkInfo.keyType) && !!getIndexTypeOfType(base, info.keyType)) ? interfaceDeclaration : undefined); if (errorNode && !isTypeAssignableTo(checkInfo.type, info.type)) { - error(errorNode, Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, - typeToString(checkInfo.type), typeToString(info.type)); + error(errorNode, Diagnostics._0_index_type_1_is_not_assignable_to_2_index_type_3, + typeToString(checkInfo.keyType), typeToString(checkInfo.type), typeToString(info.keyType), typeToString(info.type)); } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4749921ca2f81..fdb10eaf5b0ed 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1846,15 +1846,11 @@ "category": "Error", "code": 2410 }, - "Property '{0}' of type '{1}' is not assignable to string index type '{2}'.": { + "Property '{0}' of type '{1}' is not assignable to '{2}' index type '{3}'.": { "category": "Error", "code": 2411 }, - "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'.": { - "category": "Error", - "code": 2412 - }, - "Numeric index type '{0}' is not assignable to string index type '{1}'.": { + "'{0}' index type '{1}' is not assignable to '{2}' index type '{3}'.": { "category": "Error", "code": 2413 }, diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts index 9728cc032f250..c25d6efd62f48 100644 --- a/src/services/codefixes/fixInvalidImportSyntax.ts +++ b/src/services/codefixes/fixInvalidImportSyntax.ts @@ -57,9 +57,8 @@ namespace ts.codefix { Diagnostics.Type_0_is_not_assignable_to_type_1.code, Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated.code, Diagnostics.Type_predicate_0_is_not_assignable_to_1.code, - Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2.code, - Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2.code, - Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1.code, + Diagnostics.Property_0_of_type_1_is_not_assignable_to_2_index_type_3.code, + Diagnostics._0_index_type_1_is_not_assignable_to_2_index_type_3.code, Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2.code, Diagnostics.Property_0_in_type_1_is_not_assignable_to_type_2.code, Diagnostics.Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property.code, From f2a20cc4d43698913fccd9de3347e155ff9e5b01 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Jun 2021 08:51:02 -0700 Subject: [PATCH 24/56] Accept new baselines --- .../reference/classIndexer2.errors.txt | 4 +- .../reference/classIndexer3.errors.txt | 4 +- .../reference/classIndexer4.errors.txt | 4 +- .../computedPropertyNames36_ES5.errors.txt | 4 +- .../computedPropertyNames36_ES6.errors.txt | 4 +- .../computedPropertyNames38_ES5.errors.txt | 4 +- .../computedPropertyNames38_ES6.errors.txt | 4 +- .../computedPropertyNames39_ES5.errors.txt | 4 +- .../computedPropertyNames39_ES6.errors.txt | 4 +- .../computedPropertyNames40_ES5.errors.txt | 4 +- .../computedPropertyNames40_ES6.errors.txt | 4 +- .../computedPropertyNames42_ES5.errors.txt | 4 +- .../computedPropertyNames42_ES6.errors.txt | 4 +- .../computedPropertyNames43_ES5.errors.txt | 4 +- .../computedPropertyNames43_ES6.errors.txt | 4 +- .../computedPropertyNames44_ES5.errors.txt | 8 +- .../computedPropertyNames44_ES6.errors.txt | 8 +- .../computedPropertyNames45_ES5.errors.txt | 8 +- .../computedPropertyNames45_ES6.errors.txt | 8 +- ...faceIncompatibleWithBaseIndexer.errors.txt | 28 ++-- ...sNotASubtypeOfAnythingButNumber.errors.txt | 64 +++++----- ...nAndInterfaceWithSeparateErrors.errors.txt | 4 +- .../reference/indexTypeCheck.errors.txt | 12 +- .../reference/indexerConstraints.errors.txt | 16 +-- .../reference/indexerConstraints2.errors.txt | 12 +- ...dexSignaturesFromDifferentBases.errors.txt | 24 ++-- ...IndexersFromDifferentBaseTypes2.errors.txt | 4 +- .../interfaceExtendingClass2.errors.txt | 4 +- ...ExtendsObjectIntersectionErrors.errors.txt | 16 +-- .../interfaceMemberValidation.errors.txt | 4 +- ...ingIndexerHidingBaseTypeIndexer.errors.txt | 4 +- ...ngIndexerHidingBaseTypeIndexer2.errors.txt | 4 +- ...ngIndexerHidingBaseTypeIndexer3.errors.txt | 4 +- .../interfacedeclWithIndexerErrors.errors.txt | 20 +-- .../mergedInterfacesWithIndexers2.errors.txt | 12 +- ...rConstrainsPropertyDeclarations.errors.txt | 16 +-- ...ConstrainsPropertyDeclarations2.errors.txt | 12 +- .../numericIndexerConstraint.errors.txt | 4 +- ...peHidingMembersOfExtendedObject.errors.txt | 18 +-- ...tringIndexerHidingObjectIndexer.errors.txt | 14 +- .../propertiesAndIndexers.errors.txt | 76 +++++------ .../propertiesAndIndexers2.errors.txt | 36 +++--- ...rtiesAndIndexersForNumericNames.errors.txt | 32 ++--- .../staticIndexSignature3.errors.txt | 4 +- .../staticIndexSignature7.errors.txt | 8 +- .../stringIndexerAndConstructor.errors.txt | 8 +- .../stringIndexerAndConstructor1.errors.txt | 4 +- ...rConstrainsPropertyDeclarations.errors.txt | 84 ++++++------ ...ConstrainsPropertyDeclarations2.errors.txt | 24 ++-- ...sOfTypeParameterWithConstraints.errors.txt | 40 +++--- ...OfTypeParameterWithConstraints4.errors.txt | 20 +-- ...rameterWithRecursiveConstraints.errors.txt | 48 +++---- .../reference/subtypesOfUnion.errors.txt | 116 ++++++++--------- .../reference/symbolProperty17.errors.txt | 4 +- .../reference/symbolProperty30.errors.txt | 4 +- .../reference/symbolProperty32.errors.txt | 4 +- .../reference/symbolProperty34.errors.txt | 4 +- .../baselines/reference/typeName1.errors.txt | 8 +- ...IfEveryConstituentTypeIsSubtype.errors.txt | 120 +++++++++--------- 59 files changed, 516 insertions(+), 516 deletions(-) diff --git a/tests/baselines/reference/classIndexer2.errors.txt b/tests/baselines/reference/classIndexer2.errors.txt index c916ca27846b4..3d4288ec67686 100644 --- a/tests/baselines/reference/classIndexer2.errors.txt +++ b/tests/baselines/reference/classIndexer2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classIndexer2.ts(4,5): error TS2411: Property 'y' of type 'string' is not assignable to string index type 'number'. +tests/cases/compiler/classIndexer2.ts(4,5): error TS2411: Property 'y' of type 'string' is not assignable to 'string' index type 'number'. ==== tests/cases/compiler/classIndexer2.ts (1 errors) ==== @@ -7,7 +7,7 @@ tests/cases/compiler/classIndexer2.ts(4,5): error TS2411: Property 'y' of type ' x: number; y: string; ~ -!!! error TS2411: Property 'y' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'y' of type 'string' is not assignable to 'string' index type 'number'. constructor() { } } \ No newline at end of file diff --git a/tests/baselines/reference/classIndexer3.errors.txt b/tests/baselines/reference/classIndexer3.errors.txt index fbd4b35327fd6..e26993de3f8da 100644 --- a/tests/baselines/reference/classIndexer3.errors.txt +++ b/tests/baselines/reference/classIndexer3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classIndexer3.ts(9,5): error TS2411: Property 'y' of type 'string' is not assignable to string index type 'number'. +tests/cases/compiler/classIndexer3.ts(9,5): error TS2411: Property 'y' of type 'string' is not assignable to 'string' index type 'number'. ==== tests/cases/compiler/classIndexer3.ts (1 errors) ==== @@ -12,5 +12,5 @@ tests/cases/compiler/classIndexer3.ts(9,5): error TS2411: Property 'y' of type ' x: number; y: string; ~ -!!! error TS2411: Property 'y' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'y' of type 'string' is not assignable to 'string' index type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/classIndexer4.errors.txt b/tests/baselines/reference/classIndexer4.errors.txt index 5375f9610d739..d962f959f683d 100644 --- a/tests/baselines/reference/classIndexer4.errors.txt +++ b/tests/baselines/reference/classIndexer4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classIndexer4.ts(9,5): error TS2411: Property 'y' of type 'string' is not assignable to string index type 'number'. +tests/cases/compiler/classIndexer4.ts(9,5): error TS2411: Property 'y' of type 'string' is not assignable to 'string' index type 'number'. ==== tests/cases/compiler/classIndexer4.ts (1 errors) ==== @@ -12,5 +12,5 @@ tests/cases/compiler/classIndexer4.ts(9,5): error TS2411: Property 'y' of type ' x: number; y: string; ~ -!!! error TS2411: Property 'y' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'y' of type 'string' is not assignable to 'string' index type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames36_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames36_ES5.errors.txt index 506a9ca15d157..8eb67ef790d94 100644 --- a/tests/baselines/reference/computedPropertyNames36_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames36_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES5.ts(8,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES5.ts(8,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES5.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES5.ts(8, // Computed properties get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. set ["set1"](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames36_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames36_ES6.errors.txt index cf50807ac5403..dff4c670ec9b4 100644 --- a/tests/baselines/reference/computedPropertyNames36_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames36_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES6.ts(8,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES6.ts(8,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES6.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames36_ES6.ts(8, // Computed properties get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. set ["set1"](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames38_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames38_ES5.errors.txt index 2e5313caa4108..63bd17dadb7a6 100644 --- a/tests/baselines/reference/computedPropertyNames38_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames38_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES5.ts(8,9): error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES5.ts(8,9): error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES5.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES5.ts(8, // Computed properties get [1 << 6]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. set [1 << 6](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames38_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames38_ES6.errors.txt index 4c6e78c5b04f5..be02438c91008 100644 --- a/tests/baselines/reference/computedPropertyNames38_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames38_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES6.ts(8,9): error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES6.ts(8,9): error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES6.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames38_ES6.ts(8, // Computed properties get [1 << 6]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. set [1 << 6](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames39_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames39_ES5.errors.txt index a204ef4ae3402..ebc1eada2f0c2 100644 --- a/tests/baselines/reference/computedPropertyNames39_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames39_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES5.ts(8,9): error TS2412: Property '[1 << 6]' of type 'Foo' is not assignable to numeric index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES5.ts(8,9): error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'number' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES5.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES5.ts(8, // Computed properties get [1 << 6]() { return new Foo } ~~~~~~~~ -!!! error TS2412: Property '[1 << 6]' of type 'Foo' is not assignable to numeric index type 'Foo2'. +!!! error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'number' index type 'Foo2'. set [1 << 6](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames39_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames39_ES6.errors.txt index d2e2494c87ab5..471f4f32e5652 100644 --- a/tests/baselines/reference/computedPropertyNames39_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames39_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES6.ts(8,9): error TS2412: Property '[1 << 6]' of type 'Foo' is not assignable to numeric index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES6.ts(8,9): error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'number' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES6.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames39_ES6.ts(8, // Computed properties get [1 << 6]() { return new Foo } ~~~~~~~~ -!!! error TS2412: Property '[1 << 6]' of type 'Foo' is not assignable to numeric index type 'Foo2'. +!!! error TS2411: Property '[1 << 6]' of type 'Foo' is not assignable to 'number' index type 'Foo2'. set [1 << 6](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt index 40a9e9a2e3d0f..5141b2d373d5e 100644 --- a/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames40_ES5.errors.txt @@ -1,5 +1,5 @@ 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(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. @@ -15,7 +15,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES5.ts(9, ~~~~ !!! error TS2393: Duplicate function implementation. ~~~~ -!!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'. +!!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to 'string' index type '() => Foo2'. [""]() { return new Foo2 } ~~~~ !!! error TS2393: Duplicate function implementation. diff --git a/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt index 10c0a456dbea8..52f5515d3081b 100644 --- a/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames40_ES6.errors.txt @@ -1,5 +1,5 @@ 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(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. @@ -15,7 +15,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames40_ES6.ts(9, ~~~~ !!! error TS2393: Duplicate function implementation. ~~~~ -!!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to string index type '() => Foo2'. +!!! error TS2411: Property '[""]' of type '() => Foo' is not assignable to 'string' index type '() => Foo2'. [""]() { return new Foo2 } ~~~~ !!! error TS2393: Duplicate function implementation. diff --git a/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt index 0eeff51837e5f..1804df306fcbb 100644 --- a/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames42_ES5.errors.txt @@ -1,4 +1,4 @@ -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(8,5): error TS2411: Property '[""]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts (1 errors) ==== @@ -11,5 +11,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES5.ts(8, // Computed properties [""]: Foo; ~~~~ -!!! error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! 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 3dcd6e898ed9b..3459652914ff0 100644 --- a/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames42_ES6.errors.txt @@ -1,4 +1,4 @@ -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(8,5): error TS2411: Property '[""]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts (1 errors) ==== @@ -11,5 +11,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames42_ES6.ts(8, // Computed properties [""]: Foo; ~~~~ -!!! error TS2411: Property '[""]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! 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.errors.txt b/tests/baselines/reference/computedPropertyNames43_ES5.errors.txt index d777ae659defd..4b5546487f2c7 100644 --- a/tests/baselines/reference/computedPropertyNames43_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames43_ES5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES5.ts(10,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES5.ts(10,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES5.ts (1 errors) ==== @@ -13,6 +13,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES5.ts(10 // Computed properties get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. set ["set1"](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames43_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames43_ES6.errors.txt index 6af43ebfa5cb3..7110b7f6c76db 100644 --- a/tests/baselines/reference/computedPropertyNames43_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames43_ES6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES6.ts(10,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES6.ts(10,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES6.ts (1 errors) ==== @@ -13,6 +13,6 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames43_ES6.ts(10 // Computed properties get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. set ["set1"](p: Foo2) { } } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames44_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames44_ES5.errors.txt index 43801ab3d627b..1c22a30588daf 100644 --- a/tests/baselines/reference/computedPropertyNames44_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames44_ES5.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES5.ts(6,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. -tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES5.ts(10,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES5.ts(6,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES5.ts(10,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES5.ts (2 errors) ==== @@ -10,11 +10,11 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES5.ts(10 [s: string]: Foo2; get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } class D extends C { set ["set1"](p: Foo) { } ~~~~~~~~ -!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames44_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames44_ES6.errors.txt index 28b861347a37e..d602cdbe6620c 100644 --- a/tests/baselines/reference/computedPropertyNames44_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames44_ES6.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES6.ts(6,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. -tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES6.ts(10,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES6.ts(6,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES6.ts(10,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES6.ts (2 errors) ==== @@ -10,11 +10,11 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames44_ES6.ts(10 [s: string]: Foo2; get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } class D extends C { set ["set1"](p: Foo) { } ~~~~~~~~ -!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt b/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt index f06d199ba5af5..dca0d5f5a16ba 100644 --- a/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNames45_ES5.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(5,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. -tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(11,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(5,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(11,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts (2 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(11 class C { get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } class D extends C { @@ -17,5 +17,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES5.ts(11 [s: string]: Foo2; set ["set1"](p: Foo) { } ~~~~~~~~ -!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt b/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt index 626ed14ad1ad3..5bd2d5caa4a44 100644 --- a/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNames45_ES6.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(5,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. -tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(11,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(5,9): error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. +tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(11,9): error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. ==== tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts (2 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(11 class C { get ["get1"]() { return new Foo } ~~~~~~~~ -!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["get1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } class D extends C { @@ -17,5 +17,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNames45_ES6.ts(11 [s: string]: Foo2; set ["set1"](p: Foo) { } ~~~~~~~~ -!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to string index type 'Foo2'. +!!! error TS2411: Property '["set1"]' of type 'Foo' is not assignable to 'string' index type 'Foo2'. } \ No newline at end of file diff --git a/tests/baselines/reference/derivedInterfaceIncompatibleWithBaseIndexer.errors.txt b/tests/baselines/reference/derivedInterfaceIncompatibleWithBaseIndexer.errors.txt index 904a6f5fe34f2..2e09a7fa32074 100644 --- a/tests/baselines/reference/derivedInterfaceIncompatibleWithBaseIndexer.errors.txt +++ b/tests/baselines/reference/derivedInterfaceIncompatibleWithBaseIndexer.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(7,5): error TS2411: Property '1' of type '{ y: number; }' is not assignable to string index type '{ x: number; }'. -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(7,5): error TS2412: Property '1' of type '{ y: number; }' is not assignable to numeric index type '{ x: number; y: number; }'. -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(11,5): error TS2411: Property ''1'' of type '{ y: number; }' is not assignable to string index type '{ x: number; }'. -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(11,5): error TS2412: Property ''1'' of type '{ y: number; }' is not assignable to numeric index type '{ x: number; y: number; }'. -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(15,5): error TS2411: Property 'foo' of type '{ y: number; }' is not assignable to string index type '{ x: number; }'. -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(19,5): error TS2411: Property 'foo' of type '() => { x: number; }' is not assignable to string index type '{ x: number; }'. -tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(24,5): error TS2412: Property '1' of type '{ x: number; }' is not assignable to numeric index type '{ x: number; y: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(7,5): error TS2411: Property '1' of type '{ y: number; }' is not assignable to 'number' index type '{ x: number; y: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(7,5): error TS2411: Property '1' of type '{ y: number; }' is not assignable to 'string' index type '{ x: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(11,5): error TS2411: Property ''1'' of type '{ y: number; }' is not assignable to 'number' index type '{ x: number; y: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(11,5): error TS2411: Property ''1'' of type '{ y: number; }' is not assignable to 'string' index type '{ x: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(15,5): error TS2411: Property 'foo' of type '{ y: number; }' is not assignable to 'string' index type '{ x: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(19,5): error TS2411: Property 'foo' of type '() => { x: number; }' is not assignable to 'string' index type '{ x: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts(24,5): error TS2411: Property '1' of type '{ x: number; }' is not assignable to 'number' index type '{ x: number; y: number; }'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompatibleWithBaseIndexer.ts (7 errors) ==== @@ -16,36 +16,36 @@ tests/cases/conformance/interfaces/interfaceDeclarations/derivedInterfaceIncompa interface Derived extends Base { 1: { y: number } // error ~ -!!! error TS2411: Property '1' of type '{ y: number; }' is not assignable to string index type '{ x: number; }'. +!!! error TS2411: Property '1' of type '{ y: number; }' is not assignable to 'number' index type '{ x: number; y: number; }'. ~ -!!! error TS2412: Property '1' of type '{ y: number; }' is not assignable to numeric index type '{ x: number; y: number; }'. +!!! error TS2411: Property '1' of type '{ y: number; }' is not assignable to 'string' index type '{ x: number; }'. } interface Derived2 extends Base { '1': { y: number } // error ~~~ -!!! error TS2411: Property ''1'' of type '{ y: number; }' is not assignable to string index type '{ x: number; }'. +!!! error TS2411: Property ''1'' of type '{ y: number; }' is not assignable to 'number' index type '{ x: number; y: number; }'. ~~~ -!!! error TS2412: Property ''1'' of type '{ y: number; }' is not assignable to numeric index type '{ x: number; y: number; }'. +!!! error TS2411: Property ''1'' of type '{ y: number; }' is not assignable to 'string' index type '{ x: number; }'. } interface Derived3 extends Base { foo: { y: number } // error ~~~ -!!! error TS2411: Property 'foo' of type '{ y: number; }' is not assignable to string index type '{ x: number; }'. +!!! error TS2411: Property 'foo' of type '{ y: number; }' is not assignable to 'string' index type '{ x: number; }'. } interface Derived4 extends Base { foo(): { x: number } // error ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'foo' of type '() => { x: number; }' is not assignable to string index type '{ x: number; }'. +!!! error TS2411: Property 'foo' of type '() => { x: number; }' is not assignable to 'string' index type '{ x: number; }'. } // satisifies string indexer but not numeric indexer interface Derived5 extends Base { 1: { x: number } // error ~ -!!! error TS2412: Property '1' of type '{ x: number; }' is not assignable to numeric index type '{ x: number; y: number; }'. +!!! error TS2411: Property '1' of type '{ x: number; }' is not assignable to 'number' index type '{ x: number; y: number; }'. } interface Derived5 extends Base { diff --git a/tests/baselines/reference/enumIsNotASubtypeOfAnythingButNumber.errors.txt b/tests/baselines/reference/enumIsNotASubtypeOfAnythingButNumber.errors.txt index 225c0d811bc04..04115bcfb04f0 100644 --- a/tests/baselines/reference/enumIsNotASubtypeOfAnythingButNumber.errors.txt +++ b/tests/baselines/reference/enumIsNotASubtypeOfAnythingButNumber.errors.txt @@ -1,19 +1,19 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(18,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'string'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(24,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'boolean'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(30,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(36,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'RegExp'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(42,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type '{ bar: number; }'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(48,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'number[]'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(54,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'I8'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(60,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'A'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(66,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'A2'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(72,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type '(x: any) => number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(78,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type '(x: T) => T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(85,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'E2'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(95,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'typeof f'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(105,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'typeof c'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(111,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(117,5): error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(18,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(24,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'boolean'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(30,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'Date'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(36,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'RegExp'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(42,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type '{ bar: number; }'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(48,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'number[]'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(54,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'I8'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(60,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(66,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'A2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(72,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type '(x: any) => number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(78,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(85,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'E2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(95,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'typeof f'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(105,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'typeof c'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(111,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts(117,5): error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'U'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotASubtypeOfAnythingButNumber.ts (16 errors) ==== @@ -36,7 +36,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: string; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'string'. } @@ -44,7 +44,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: boolean; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'boolean'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'boolean'. } @@ -52,7 +52,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: Date; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'Date'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'Date'. } @@ -60,7 +60,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: RegExp; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'RegExp'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'RegExp'. } @@ -68,7 +68,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: { bar: number }; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type '{ bar: number; }'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type '{ bar: number; }'. } @@ -76,7 +76,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: number[]; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'number[]'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'number[]'. } @@ -84,7 +84,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: I8; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'I8'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'I8'. } class A { foo: number; } @@ -92,7 +92,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: A; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'A'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'A'. } class A2 { foo: T; } @@ -100,7 +100,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: A2; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'A2'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'A2'. } @@ -108,7 +108,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: (x) => number; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type '(x: any) => number'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type '(x: any) => number'. } @@ -116,7 +116,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: (x: T) => T; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type '(x: T) => T'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type '(x: T) => T'. } @@ -125,7 +125,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: E2; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'E2'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'E2'. } @@ -137,7 +137,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: typeof f; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'typeof f'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'typeof f'. } @@ -149,7 +149,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: typeof c; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'typeof c'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'typeof c'. } @@ -157,7 +157,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: T; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'T'. } @@ -165,7 +165,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/enumIsNotA [x: string]: U; foo: E; ~~~ -!!! error TS2411: Property 'foo' of type 'E' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'E' is not assignable to 'string' index type 'U'. } diff --git a/tests/baselines/reference/functionAndInterfaceWithSeparateErrors.errors.txt b/tests/baselines/reference/functionAndInterfaceWithSeparateErrors.errors.txt index a22bdef219965..8d9a60b0c869c 100644 --- a/tests/baselines/reference/functionAndInterfaceWithSeparateErrors.errors.txt +++ b/tests/baselines/reference/functionAndInterfaceWithSeparateErrors.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/functionAndInterfaceWithSeparateErrors.ts(1,10): error TS2394: This overload signature is not compatible with its implementation signature. -tests/cases/compiler/functionAndInterfaceWithSeparateErrors.ts(6,5): error TS2411: Property 'prop' of type 'number' is not assignable to string index type 'string'. +tests/cases/compiler/functionAndInterfaceWithSeparateErrors.ts(6,5): error TS2411: Property 'prop' of type 'number' is not assignable to 'string' index type 'string'. ==== tests/cases/compiler/functionAndInterfaceWithSeparateErrors.ts (2 errors) ==== @@ -13,5 +13,5 @@ tests/cases/compiler/functionAndInterfaceWithSeparateErrors.ts(6,5): error TS241 [s: string]: string; prop: number; ~~~~ -!!! error TS2411: Property 'prop' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'prop' of type 'number' is not assignable to 'string' index type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/indexTypeCheck.errors.txt b/tests/baselines/reference/indexTypeCheck.errors.txt index ea2e14103323f..a5582cb67e093 100644 --- a/tests/baselines/reference/indexTypeCheck.errors.txt +++ b/tests/baselines/reference/indexTypeCheck.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/indexTypeCheck.ts(2,2): error TS1021: An index signature must have a type annotation. tests/cases/compiler/indexTypeCheck.ts(3,2): error TS1021: An index signature must have a type annotation. -tests/cases/compiler/indexTypeCheck.ts(17,2): error TS2413: Numeric index type 'number' is not assignable to string index type 'string'. -tests/cases/compiler/indexTypeCheck.ts(22,2): error TS2413: Numeric index type 'Orange' is not assignable to string index type 'Yellow'. -tests/cases/compiler/indexTypeCheck.ts(27,2): error TS2413: Numeric index type 'number' is not assignable to string index type 'string'. +tests/cases/compiler/indexTypeCheck.ts(17,2): error TS2413: 'number' index type 'number' is not assignable to 'string' index type 'string'. +tests/cases/compiler/indexTypeCheck.ts(22,2): error TS2413: 'number' index type 'Orange' is not assignable to 'string' index type 'Yellow'. +tests/cases/compiler/indexTypeCheck.ts(27,2): error TS2413: 'number' index type 'number' is not assignable to 'string' index type 'string'. tests/cases/compiler/indexTypeCheck.ts(32,3): error TS1096: An index signature must have exactly one parameter. tests/cases/compiler/indexTypeCheck.ts(36,3): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/indexTypeCheck.ts(51,8): error TS2538: Type 'Blue' cannot be used as an index type. @@ -31,21 +31,21 @@ tests/cases/compiler/indexTypeCheck.ts(51,8): error TS2538: Type 'Blue' cannot b interface Orange { [n:number]: number; // ok ~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'number' is not assignable to string index type 'string'. +!!! error TS2413: 'number' index type 'number' is not assignable to 'string' index type 'string'. [s:string]: string; // error } interface Green { [n:number]: Orange; // error ~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'Orange' is not assignable to string index type 'Yellow'. +!!! error TS2413: 'number' index type 'Orange' is not assignable to 'string' index type 'Yellow'. [s:string]: Yellow; // ok } interface Cyan { [n:number]: number; // error ~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'number' is not assignable to string index type 'string'. +!!! error TS2413: 'number' index type 'number' is not assignable to 'string' index type 'string'. [s:string]: string; // ok } diff --git a/tests/baselines/reference/indexerConstraints.errors.txt b/tests/baselines/reference/indexerConstraints.errors.txt index cb7785535d18a..8fc8c0dbb2b26 100644 --- a/tests/baselines/reference/indexerConstraints.errors.txt +++ b/tests/baselines/reference/indexerConstraints.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/indexerConstraints.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints.ts(25,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints.ts(33,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints.ts(41,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +tests/cases/compiler/indexerConstraints.ts(17,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. +tests/cases/compiler/indexerConstraints.ts(25,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. +tests/cases/compiler/indexerConstraints.ts(33,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. +tests/cases/compiler/indexerConstraints.ts(41,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. ==== tests/cases/compiler/indexerConstraints.ts (4 errors) ==== @@ -23,7 +23,7 @@ tests/cases/compiler/indexerConstraints.ts(41,5): error TS2413: Numeric index ty interface E { [n: number]: A; ~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. } // Inheritance @@ -33,7 +33,7 @@ tests/cases/compiler/indexerConstraints.ts(41,5): error TS2413: Numeric index ty interface G extends F { [n: number]: A; ~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. } // Other way @@ -43,7 +43,7 @@ tests/cases/compiler/indexerConstraints.ts(41,5): error TS2413: Numeric index ty interface I extends H { [s: string]: B; ~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. } // With hidden indexer @@ -53,6 +53,6 @@ tests/cases/compiler/indexerConstraints.ts(41,5): error TS2413: Numeric index ty interface K extends J { [n: number]: A; ~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. [s: string]: B; } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 5a4dca341b28a..8863b842e7f43 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. -tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. +tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. +tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. @@ -21,7 +21,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signat class G extends F { [n: number]: A ~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. } // Other way @@ -31,7 +31,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signat class I extends H { [s: string]: B ~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. } // With hidden indexer @@ -42,7 +42,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signat class K extends J { [n: number]: A; ~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +!!! error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. [s: string]: B; } diff --git a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.errors.txt b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.errors.txt index d2ad69730dad7..37f760da890a7 100644 --- a/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.errors.txt +++ b/tests/baselines/reference/inheritedMembersAndIndexSignaturesFromDifferentBases.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(17,11): error TS2411: Property 'm' of type '{}' is not assignable to string index type '{ a: any; }'. -tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(23,11): error TS2411: Property '0' of type '{}' is not assignable to string index type '{ a: any; }'. -tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(23,11): error TS2412: Property '0' of type '{}' is not assignable to numeric index type '{ a: any; b: any; }'. -tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25,11): error TS2411: Property '0' of type '{}' is not assignable to string index type '{ a: any; }'. -tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25,11): error TS2411: Property 'm' of type '{}' is not assignable to string index type '{ a: any; }'. -tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25,11): error TS2412: Property '0' of type '{}' is not assignable to numeric index type '{ a: any; b: any; }'. +tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(17,11): error TS2411: Property 'm' of type '{}' is not assignable to 'string' index type '{ a: any; }'. +tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(23,11): error TS2411: Property '0' of type '{}' is not assignable to 'number' index type '{ a: any; b: any; }'. +tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(23,11): error TS2411: Property '0' of type '{}' is not assignable to 'string' index type '{ a: any; }'. +tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25,11): error TS2411: Property '0' of type '{}' is not assignable to 'number' index type '{ a: any; b: any; }'. +tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25,11): error TS2411: Property '0' of type '{}' is not assignable to 'string' index type '{ a: any; }'. +tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25,11): error TS2411: Property 'm' of type '{}' is not assignable to 'string' index type '{ a: any; }'. ==== tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts (6 errors) ==== @@ -25,7 +25,7 @@ tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25, interface D extends A, B, C { } // error because m is not a subtype of {a;} ~ -!!! error TS2411: Property 'm' of type '{}' is not assignable to string index type '{ a: any; }'. +!!! error TS2411: Property 'm' of type '{}' is not assignable to 'string' index type '{ a: any; }'. interface E { 0: {}; @@ -33,16 +33,16 @@ tests/cases/compiler/inheritedMembersAndIndexSignaturesFromDifferentBases.ts(25, interface F extends A, B, E { } // error because 0 is not a subtype of {a; b;} ~ -!!! error TS2411: Property '0' of type '{}' is not assignable to string index type '{ a: any; }'. +!!! error TS2411: Property '0' of type '{}' is not assignable to 'number' index type '{ a: any; b: any; }'. ~ -!!! error TS2412: Property '0' of type '{}' is not assignable to numeric index type '{ a: any; b: any; }'. +!!! error TS2411: Property '0' of type '{}' is not assignable to 'string' index type '{ a: any; }'. interface G extends A, B, C, E { } // should only report one error ~ -!!! error TS2411: Property '0' of type '{}' is not assignable to string index type '{ a: any; }'. +!!! error TS2411: Property '0' of type '{}' is not assignable to 'number' index type '{ a: any; b: any; }'. ~ -!!! error TS2411: Property 'm' of type '{}' is not assignable to string index type '{ a: any; }'. +!!! error TS2411: Property '0' of type '{}' is not assignable to 'string' index type '{ a: any; }'. ~ -!!! error TS2412: Property '0' of type '{}' is not assignable to numeric index type '{ a: any; b: any; }'. +!!! error TS2411: Property 'm' of type '{}' is not assignable to 'string' index type '{ a: any; }'. interface H extends A, F { } // Should report no error at all because error is internal to F \ No newline at end of file diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.errors.txt b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.errors.txt index 8e6fc5b3158e3..0a39b402bc5f3 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.errors.txt +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes2.ts(18,11): error TS2413: Numeric index type '{}' is not assignable to string index type '{ a: any; }'. +tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes2.ts(18,11): error TS2413: 'number' index type '{}' is not assignable to 'string' index type '{ a: any; }'. ==== tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes2.ts (1 errors) ==== @@ -21,7 +21,7 @@ tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes2.ts(18,11): e } interface E extends A, D { } // error ~ -!!! error TS2413: Numeric index type '{}' is not assignable to string index type '{ a: any; }'. +!!! error TS2413: 'number' index type '{}' is not assignable to 'string' index type '{ a: any; }'. interface F extends A, D { [s: number]: { diff --git a/tests/baselines/reference/interfaceExtendingClass2.errors.txt b/tests/baselines/reference/interfaceExtendingClass2.errors.txt index 8c15a845ce845..117da5411d655 100644 --- a/tests/baselines/reference/interfaceExtendingClass2.errors.txt +++ b/tests/baselines/reference/interfaceExtendingClass2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClass2.ts(11,5): error TS2411: Property 'a' of type '{ toString: () => {}; }' is not assignable to string index type 'Object'. +tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClass2.ts(11,5): error TS2411: Property 'a' of type '{ toString: () => {}; }' is not assignable to 'string' index type 'Object'. tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClass2.ts(13,13): error TS1131: Property or signature expected. tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClass2.ts(14,9): error TS1128: Declaration or statement expected. tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClass2.ts(15,5): error TS1128: Declaration or statement expected. @@ -17,7 +17,7 @@ tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtending interface I2 extends Foo { // error a: { ~ -!!! error TS2411: Property 'a' of type '{ toString: () => {}; }' is not assignable to string index type 'Object'. +!!! error TS2411: Property 'a' of type '{ toString: () => {}; }' is not assignable to 'string' index type 'Object'. toString: () => { return 1; ~~~~~~ diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt index 17cb5585cf87e..1f7f560338c53 100644 --- a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -33,10 +33,10 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(32,11): error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. Types of property 'a' are incompatible. Type 'number' is not assignable to type '"hello"'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,29): error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,29): error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(35,29): error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,29): error TS2411: Property 'a' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,29): error TS2411: Property 'prototype' of type 'CX' is not assignable to 'string' index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2413: 'number' index type 'string' is not assignable to 'string' index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(35,29): error TS2411: Property 'a' of type '"hello"' is not assignable to 'string' index type 'number'. tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(39,11): error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. Types of property 'a' are incompatible. Type 'string' is not assignable to type 'number | undefined'. @@ -138,15 +138,15 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectI !!! error TS2430: Type 'number' is not assignable to type '"hello"'. interface I14 extends TCX { [x: string]: number } ~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'a' of type 'string' is not assignable to 'string' index type 'number'. ~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. +!!! error TS2411: Property 'prototype' of type 'CX' is not assignable to 'string' index type 'number'. interface I15 extends TEX { [x: string]: number } ~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. +!!! error TS2413: 'number' index type 'string' is not assignable to 'string' index type 'number'. interface I16 extends TNX { [x: string]: number } ~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. +!!! error TS2411: Property 'a' of type '"hello"' is not assignable to 'string' index type 'number'. type Identifiable = { _id: string } & T; diff --git a/tests/baselines/reference/interfaceMemberValidation.errors.txt b/tests/baselines/reference/interfaceMemberValidation.errors.txt index 3b2b1d1874c21..53274b7592fce 100644 --- a/tests/baselines/reference/interfaceMemberValidation.errors.txt +++ b/tests/baselines/reference/interfaceMemberValidation.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/interfaceMemberValidation.ts(2,11): error TS2430: Interface 'i2' incorrectly extends interface 'i1'. Types of property 'name' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/compiler/interfaceMemberValidation.ts(5,2): error TS2411: Property 'bar' of type '{ (): any; (): any; }' is not assignable to string index type 'number'. +tests/cases/compiler/interfaceMemberValidation.ts(5,2): error TS2411: Property 'bar' of type '{ (): any; (): any; }' is not assignable to 'string' index type 'number'. tests/cases/compiler/interfaceMemberValidation.ts(10,2): error TS2374: Duplicate string index signature. @@ -16,7 +16,7 @@ tests/cases/compiler/interfaceMemberValidation.ts(10,2): error TS2374: Duplicate interface foo { bar():any; ~~~~~~~~~~ -!!! error TS2411: Property 'bar' of type '{ (): any; (): any; }' is not assignable to string index type 'number'. +!!! error TS2411: Property 'bar' of type '{ (): any; (): any; }' is not assignable to 'string' index type 'number'. bar():any; new():void; new():void; diff --git a/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer.errors.txt b/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer.errors.txt index a604a7dc2ec65..7de34bae4e8bc 100644 --- a/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer.errors.txt +++ b/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer.ts(13,5): error TS2411: Property 'y' of type '{ a: number; }' is not assignable to string index type '{ a: number; b: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer.ts(13,5): error TS2411: Property 'y' of type '{ a: number; }' is not assignable to 'string' index type '{ a: number; b: number; }'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer.ts (1 errors) ==== @@ -16,7 +16,7 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringInde // error y: { ~ -!!! error TS2411: Property 'y' of type '{ a: number; }' is not assignable to string index type '{ a: number; b: number; }'. +!!! error TS2411: Property 'y' of type '{ a: number; }' is not assignable to 'string' index type '{ a: number; b: number; }'. a: number; } } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer2.errors.txt b/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer2.errors.txt index a7043f93821db..5446d05c18f95 100644 --- a/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer2.errors.txt +++ b/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer2.ts(17,5): error TS2412: Property '1' of type '{ a: number; }' is not assignable to numeric index type '{ a: number; b: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer2.ts(17,5): error TS2411: Property '1' of type '{ a: number; }' is not assignable to 'number' index type '{ a: number; b: number; }'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer2.ts (1 errors) ==== @@ -20,7 +20,7 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringInde // error 1: { ~ -!!! error TS2412: Property '1' of type '{ a: number; }' is not assignable to numeric index type '{ a: number; b: number; }'. +!!! error TS2411: Property '1' of type '{ a: number; }' is not assignable to 'number' index type '{ a: number; b: number; }'. a: number; } } \ No newline at end of file diff --git a/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer3.errors.txt b/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer3.errors.txt index b70d4b4a12d81..651ad7ee16298 100644 --- a/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer3.errors.txt +++ b/tests/baselines/reference/interfaceWithStringIndexerHidingBaseTypeIndexer3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer3.ts(13,5): error TS2412: Property '2' of type '{ a: number; }' is not assignable to numeric index type '{ a: number; b: number; }'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer3.ts(13,5): error TS2411: Property '2' of type '{ a: number; }' is not assignable to 'number' index type '{ a: number; b: number; }'. ==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringIndexerHidingBaseTypeIndexer3.ts (1 errors) ==== @@ -16,7 +16,7 @@ tests/cases/conformance/interfaces/interfaceDeclarations/interfaceWithStringInde // error 2: { ~ -!!! error TS2412: Property '2' of type '{ a: number; }' is not assignable to numeric index type '{ a: number; b: number; }'. +!!! error TS2411: Property '2' of type '{ a: number; }' is not assignable to 'number' index type '{ a: number; b: number; }'. a: number; } } \ No newline at end of file diff --git a/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt b/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt index b13b98a1da0b8..2939a04948a49 100644 --- a/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt +++ b/tests/baselines/reference/interfacedeclWithIndexerErrors.errors.txt @@ -1,8 +1,8 @@ -tests/cases/compiler/interfacedeclWithIndexerErrors.ts(12,5): error TS2411: Property 'p2' of type 'string' is not assignable to string index type '() => string'. -tests/cases/compiler/interfacedeclWithIndexerErrors.ts(14,5): error TS2411: Property 'p4' of type 'number' is not assignable to string index type '() => string'. -tests/cases/compiler/interfacedeclWithIndexerErrors.ts(15,5): error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to string index type '() => string'. -tests/cases/compiler/interfacedeclWithIndexerErrors.ts(19,5): error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to string index type '() => string'. -tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to string index type '() => string'. +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(12,5): error TS2411: Property 'p2' of type 'string' is not assignable to 'string' index type '() => string'. +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(14,5): error TS2411: Property 'p4' of type 'number' is not assignable to 'string' index type '() => string'. +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(15,5): error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to 'string' index type '() => string'. +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(19,5): error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to 'string' index type '() => string'. +tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to 'string' index type '() => string'. ==== tests/cases/compiler/interfacedeclWithIndexerErrors.ts (5 errors) ==== @@ -19,23 +19,23 @@ tests/cases/compiler/interfacedeclWithIndexerErrors.ts(20,5): error TS2411: Prop p1; p2: string; ~~ -!!! error TS2411: Property 'p2' of type 'string' is not assignable to string index type '() => string'. +!!! error TS2411: Property 'p2' of type 'string' is not assignable to 'string' index type '() => string'. p3?; p4?: number; ~~ -!!! error TS2411: Property 'p4' of type 'number' is not assignable to string index type '() => string'. +!!! error TS2411: Property 'p4' of type 'number' is not assignable to 'string' index type '() => string'. p5: (s: number) =>string; ~~ -!!! error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to string index type '() => string'. +!!! error TS2411: Property 'p5' of type '(s: number) => string' is not assignable to 'string' index type '() => string'. f1(); f2? (); f3(a: string): number; ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to string index type '() => string'. +!!! error TS2411: Property 'f3' of type '(a: string) => number' is not assignable to 'string' index type '() => string'. f4? (s: number): string; ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to string index type '() => string'. +!!! error TS2411: Property 'f4' of type '(s: number) => string' is not assignable to 'string' index type '() => string'. } diff --git a/tests/baselines/reference/mergedInterfacesWithIndexers2.errors.txt b/tests/baselines/reference/mergedInterfacesWithIndexers2.errors.txt index f649b5469937d..449760f8aa796 100644 --- a/tests/baselines/reference/mergedInterfacesWithIndexers2.errors.txt +++ b/tests/baselines/reference/mergedInterfacesWithIndexers2.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts(4,5): error TS2413: Numeric index type 'string' is not assignable to string index type '{ length: string; }'. -tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts(14,5): error TS2411: Property ''a'' of type 'number' is not assignable to string index type '{ length: number; }'. -tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts(20,5): error TS2412: Property '1' of type '{ length: number; }' is not assignable to numeric index type 'string'. +tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts(4,5): error TS2413: 'number' index type 'string' is not assignable to 'string' index type '{ length: string; }'. +tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts(14,5): error TS2411: Property ''a'' of type 'number' is not assignable to 'string' index type '{ length: number; }'. +tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts(20,5): error TS2411: Property '1' of type '{ length: number; }' is not assignable to 'number' index type 'string'. ==== tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexers2.ts (3 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexe interface A { [x: number]: string; // error ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'string' is not assignable to string index type '{ length: string; }'. +!!! error TS2413: 'number' index type 'string' is not assignable to 'string' index type '{ length: string; }'. } @@ -21,7 +21,7 @@ tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexe [x: number]: string; 'a': number; //error ~~~ -!!! error TS2411: Property ''a'' of type 'number' is not assignable to string index type '{ length: number; }'. +!!! error TS2411: Property ''a'' of type 'number' is not assignable to 'string' index type '{ length: number; }'. } @@ -29,6 +29,6 @@ tests/cases/conformance/interfaces/declarationMerging/mergedInterfacesWithIndexe [x: string]: { length: number }; 1: { length: number }; // error ~ -!!! error TS2412: Property '1' of type '{ length: number; }' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '1' of type '{ length: number; }' is not assignable to 'number' index type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt index 82a5659c5b0a5..c39ba4d38681d 100644 --- a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt +++ b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt @@ -1,10 +1,10 @@ -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(18,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(21,5): error TS2412: Property '3.0' of type 'MyNumber' is not assignable to numeric index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(18,5): error TS2411: Property '2.0' of type 'number' is not assignable to 'number' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(21,5): error TS2411: Property '3.0' of type 'MyNumber' is not assignable to 'number' index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(23,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(26,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(36,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2411: Property '2.0' of type 'number' is not assignable to 'number' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2411: Property '2.0' of type 'number' is not assignable to 'number' index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(85,5): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(88,9): error TS2304: Cannot find name 'Myn'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. @@ -31,12 +31,12 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo 1.0: string; // ok 2.0: number; // error ~~~ -!!! error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '2.0' of type 'number' is not assignable to 'number' index type 'string'. "3.0": string; // ok "4.0": number; // error 3.0: MyNumber // error ~~~ -!!! error TS2412: Property '3.0' of type 'MyNumber' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '3.0' of type 'MyNumber' is not assignable to 'number' index type 'string'. get X() { // ok ~ @@ -73,7 +73,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo 1.0: string; // ok 2.0: number; // error ~~~ -!!! error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '2.0' of type 'number' is not assignable to 'number' index type 'string'. (): string; // ok (x): number // ok foo(): string; // ok @@ -93,7 +93,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo 1.0: string; // ok 2.0: number; // error ~~~ -!!! error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '2.0' of type 'number' is not assignable to 'number' index type 'string'. (): string; // ok (x): number // ok foo(): string; // ok diff --git a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt index 0807af21960a0..dd071af635c3b 100644 --- a/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt +++ b/tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(25,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(34,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2411: Property '3.0' of type 'number' is not assignable to 'number' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(25,5): error TS2411: Property '3.0' of type 'number' is not assignable to 'number' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(34,5): error TS2411: Property '3.0' of type 'number' is not assignable to 'number' index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(43,5): error TS2322: Type 'number' is not assignable to type 'A'. @@ -22,7 +22,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo "2.5": B // ok 3.0: number; // error ~~~ -!!! error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. +!!! error TS2411: Property '3.0' of type 'number' is not assignable to 'number' index type 'A'. "4.0": string; // error } @@ -33,7 +33,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo "2.5": B // ok 3.0: number; // error ~~~ -!!! error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. +!!! error TS2411: Property '3.0' of type 'number' is not assignable to 'number' index type 'A'. "4.0": string; // error } @@ -44,7 +44,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo "2.5": B // ok 3.0: number; // error ~~~ -!!! error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'. +!!! error TS2411: Property '3.0' of type 'number' is not assignable to 'number' index type 'A'. "4.0": string; // error }; diff --git a/tests/baselines/reference/numericIndexerConstraint.errors.txt b/tests/baselines/reference/numericIndexerConstraint.errors.txt index 21d52dee68313..b000eec8b0a1e 100644 --- a/tests/baselines/reference/numericIndexerConstraint.errors.txt +++ b/tests/baselines/reference/numericIndexerConstraint.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/numericIndexerConstraint.ts(2,5): error TS2412: Property '0' of type 'number' is not assignable to numeric index type 'RegExp'. +tests/cases/compiler/numericIndexerConstraint.ts(2,5): error TS2411: Property '0' of type 'number' is not assignable to 'number' index type 'RegExp'. ==== tests/cases/compiler/numericIndexerConstraint.ts (1 errors) ==== class C { 0: number; ~ -!!! error TS2412: Property '0' of type 'number' is not assignable to numeric index type 'RegExp'. +!!! error TS2411: Property '0' of type 'number' is not assignable to 'number' index type 'RegExp'. [x: number]: RegExp; } \ No newline at end of file diff --git a/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt b/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt index 3a2a4ed691f1a..60ba9fa57667a 100644 --- a/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt +++ b/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(10,5): error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. -lib.es5.d.ts(122,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. -lib.es5.d.ts(125,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. -lib.es5.d.ts(128,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. -lib.es5.d.ts(131,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. -lib.es5.d.ts(137,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -lib.es5.d.ts(143,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. -lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. +tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(10,5): error TS2411: Property 'data' of type 'A' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(122,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(125,5): error TS2411: Property 'toString' of type '() => string' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(128,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(131,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(137,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(143,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to 'string' index type 'Object'. ==== tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts (1 errors) ==== @@ -20,7 +20,7 @@ lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: interface Object { data: A; ~~~~ -!!! error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. +!!! error TS2411: Property 'data' of type 'A' is not assignable to 'string' index type 'Object'. [x: string]: Object; } diff --git a/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt b/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt index b244bb47413cb..54c1fd57aa2d4 100644 --- a/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt +++ b/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt @@ -1,10 +1,10 @@ -lib.es5.d.ts(122,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. -lib.es5.d.ts(125,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. -lib.es5.d.ts(128,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. -lib.es5.d.ts(131,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. -lib.es5.d.ts(137,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. -lib.es5.d.ts(143,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. -lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to string index type 'Object'. +lib.es5.d.ts(122,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(125,5): error TS2411: Property 'toString' of type '() => string' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(128,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(131,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(137,5): error TS2411: Property 'hasOwnProperty' of type '(v: PropertyKey) => boolean' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(143,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to 'string' index type 'Object'. +lib.es5.d.ts(149,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: PropertyKey) => boolean' is not assignable to 'string' index type 'Object'. ==== tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts (0 errors) ==== diff --git a/tests/baselines/reference/propertiesAndIndexers.errors.txt b/tests/baselines/reference/propertiesAndIndexers.errors.txt index a8c5fe04d2af3..37ce644e98217 100644 --- a/tests/baselines/reference/propertiesAndIndexers.errors.txt +++ b/tests/baselines/reference/propertiesAndIndexers.errors.txt @@ -1,22 +1,22 @@ -tests/cases/compiler/propertiesAndIndexers.ts(16,5): error TS2412: Property '1' of type 'Z' is not assignable to numeric index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(18,5): error TS2412: Property '3' of type 'boolean' is not assignable to numeric index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(19,5): error TS2412: Property '6' of type '() => string' is not assignable to numeric index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(23,5): error TS2412: Property '4' of type 'boolean' is not assignable to numeric index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(28,5): error TS2411: Property '1' of type 'Z' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(28,5): error TS2411: Property 'a' of type 'Y' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(28,5): error TS2411: Property 'b' of type 'X' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(29,5): error TS2411: Property 'c' of type 'boolean' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(30,5): error TS2411: Property '3' of type 'boolean' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2411: Property '4' of type 'boolean' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2411: Property '5' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2411: Property '6' of type '() => string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(34,5): error TS2411: Property '2' of type 'Z' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(34,5): error TS2412: Property '2' of type 'Z' is not assignable to numeric index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(35,5): error TS2412: Property 'Infinity' of type 'number' is not assignable to numeric index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(36,5): error TS2411: Property 'zoo' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers.ts(44,5): error TS2411: Property 't' of type 'number' is not assignable to string index type 'string'. -tests/cases/compiler/propertiesAndIndexers.ts(50,5): error TS2412: Property '3' of type 'boolean' is not assignable to numeric index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(16,5): error TS2411: Property '1' of type 'Z' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(18,5): error TS2411: Property '3' of type 'boolean' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(19,5): error TS2411: Property '6' of type '() => string' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(23,5): error TS2411: Property '4' of type 'boolean' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(28,5): error TS2411: Property '1' of type 'Z' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(28,5): error TS2411: Property 'a' of type 'Y' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(28,5): error TS2411: Property 'b' of type 'X' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(29,5): error TS2411: Property 'c' of type 'boolean' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(30,5): error TS2411: Property '3' of type 'boolean' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2411: Property '4' of type 'boolean' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2411: Property '5' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2411: Property '6' of type '() => string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(33,11): error TS2413: 'number' index type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(34,5): error TS2411: Property '2' of type 'Z' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(34,5): error TS2411: Property '2' of type 'Z' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(35,5): error TS2411: Property 'Infinity' of type 'number' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(36,5): error TS2411: Property 'zoo' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers.ts(44,5): error TS2411: Property 't' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/compiler/propertiesAndIndexers.ts(50,5): error TS2411: Property '3' of type 'boolean' is not assignable to 'number' index type 'string'. ==== tests/cases/compiler/propertiesAndIndexers.ts (19 errors) ==== @@ -37,59 +37,59 @@ tests/cases/compiler/propertiesAndIndexers.ts(50,5): error TS2412: Property '3' interface B extends A { [n: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2412: Property '1' of type 'Z' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '1' of type 'Z' is not assignable to 'number' index type 'string'. c: boolean; 3: boolean; ~ -!!! error TS2412: Property '3' of type 'boolean' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '3' of type 'boolean' is not assignable to 'number' index type 'string'. 6(): string; ~~~~~~~~~~~~ -!!! error TS2412: Property '6' of type '() => string' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '6' of type '() => string' is not assignable to 'number' index type 'string'. } interface B { 4: boolean; ~ -!!! error TS2412: Property '4' of type 'boolean' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '4' of type 'boolean' is not assignable to 'number' index type 'string'. 5: string; } interface C extends A { [s: string]: number; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property '1' of type 'Z' is not assignable to string index type 'number'. +!!! error TS2411: Property '1' of type 'Z' is not assignable to 'string' index type 'number'. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'a' of type 'Y' is not assignable to string index type 'number'. +!!! error TS2411: Property 'a' of type 'Y' is not assignable to 'string' index type 'number'. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'b' of type 'X' is not assignable to string index type 'number'. +!!! error TS2411: Property 'b' of type 'X' is not assignable to 'string' index type 'number'. c: boolean; ~ -!!! error TS2411: Property 'c' of type 'boolean' is not assignable to string index type 'number'. +!!! error TS2411: Property 'c' of type 'boolean' is not assignable to 'string' index type 'number'. 3: boolean; ~ -!!! error TS2411: Property '3' of type 'boolean' is not assignable to string index type 'number'. +!!! error TS2411: Property '3' of type 'boolean' is not assignable to 'string' index type 'number'. } interface D extends B, C { ~ -!!! error TS2411: Property '4' of type 'boolean' is not assignable to string index type 'number'. +!!! error TS2411: Property '4' of type 'boolean' is not assignable to 'string' index type 'number'. ~ -!!! error TS2411: Property '5' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property '5' of type 'string' is not assignable to 'string' index type 'number'. ~ -!!! error TS2411: Property '6' of type '() => string' is not assignable to string index type 'number'. +!!! error TS2411: Property '6' of type '() => string' is not assignable to 'string' index type 'number'. ~ -!!! error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. +!!! error TS2413: 'number' index type 'string' is not assignable to 'string' index type 'number'. 2: Z; ~ -!!! error TS2411: Property '2' of type 'Z' is not assignable to string index type 'number'. +!!! error TS2411: Property '2' of type 'Z' is not assignable to 'number' index type 'string'. ~ -!!! error TS2412: Property '2' of type 'Z' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '2' of type 'Z' is not assignable to 'string' index type 'number'. Infinity: number; ~~~~~~~~ -!!! error TS2412: Property 'Infinity' of type 'number' is not assignable to numeric index type 'string'. +!!! error TS2411: Property 'Infinity' of type 'number' is not assignable to 'number' index type 'string'. zoo: string; ~~~ -!!! error TS2411: Property 'zoo' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'zoo' of type 'string' is not assignable to 'string' index type 'number'. } class P { @@ -99,7 +99,7 @@ tests/cases/compiler/propertiesAndIndexers.ts(50,5): error TS2412: Property '3' class Q extends P { t: number; ~ -!!! error TS2411: Property 't' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 't' of type 'number' is not assignable to 'string' index type 'string'. } var c: { @@ -107,5 +107,5 @@ tests/cases/compiler/propertiesAndIndexers.ts(50,5): error TS2412: Property '3' c: boolean; 3: boolean; ~ -!!! error TS2412: Property '3' of type 'boolean' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '3' of type 'boolean' is not assignable to 'number' index type 'string'. }; \ No newline at end of file diff --git a/tests/baselines/reference/propertiesAndIndexers2.errors.txt b/tests/baselines/reference/propertiesAndIndexers2.errors.txt index a616075599a77..27d30f6447b12 100644 --- a/tests/baselines/reference/propertiesAndIndexers2.errors.txt +++ b/tests/baselines/reference/propertiesAndIndexers2.errors.txt @@ -1,19 +1,19 @@ -tests/cases/compiler/propertiesAndIndexers2.ts(2,5): error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(8,5): error TS2411: Property 'c' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(9,5): error TS2411: Property '3' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(10,5): error TS2411: Property 'Infinity' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(11,5): error TS2411: Property '"-Infinity"' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(12,5): error TS2411: Property 'NaN' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(13,5): error TS2411: Property '"-NaN"' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(14,5): error TS2411: Property '6' of type '() => string' is not assignable to string index type 'number'. -tests/cases/compiler/propertiesAndIndexers2.ts(14,5): error TS2412: Property '6' of type '() => string' is not assignable to numeric index type 'string'. +tests/cases/compiler/propertiesAndIndexers2.ts(2,5): error TS2413: 'number' index type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(8,5): error TS2411: Property 'c' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(9,5): error TS2411: Property '3' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(10,5): error TS2411: Property 'Infinity' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(11,5): error TS2411: Property '"-Infinity"' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(12,5): error TS2411: Property 'NaN' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(13,5): error TS2411: Property '"-NaN"' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/propertiesAndIndexers2.ts(14,5): error TS2411: Property '6' of type '() => string' is not assignable to 'number' index type 'string'. +tests/cases/compiler/propertiesAndIndexers2.ts(14,5): error TS2411: Property '6' of type '() => string' is not assignable to 'string' index type 'number'. ==== tests/cases/compiler/propertiesAndIndexers2.ts (9 errors) ==== interface A { [n: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. +!!! error TS2413: 'number' index type 'string' is not assignable to 'string' index type 'number'. [s: string]: number; } @@ -21,26 +21,26 @@ tests/cases/compiler/propertiesAndIndexers2.ts(14,5): error TS2412: Property '6' interface B extends A { c: string; ~ -!!! error TS2411: Property 'c' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'c' of type 'string' is not assignable to 'string' index type 'number'. 3: string; ~ -!!! error TS2411: Property '3' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property '3' of type 'string' is not assignable to 'string' index type 'number'. Infinity: string; ~~~~~~~~ -!!! error TS2411: Property 'Infinity' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'Infinity' of type 'string' is not assignable to 'string' index type 'number'. "-Infinity": string; ~~~~~~~~~~~ -!!! error TS2411: Property '"-Infinity"' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property '"-Infinity"' of type 'string' is not assignable to 'string' index type 'number'. NaN: string; ~~~ -!!! error TS2411: Property 'NaN' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'NaN' of type 'string' is not assignable to 'string' index type 'number'. "-NaN": string; ~~~~~~ -!!! error TS2411: Property '"-NaN"' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property '"-NaN"' of type 'string' is not assignable to 'string' index type 'number'. 6(): string; ~~~~~~~~~~~~ -!!! error TS2411: Property '6' of type '() => string' is not assignable to string index type 'number'. +!!! error TS2411: Property '6' of type '() => string' is not assignable to 'number' index type 'string'. ~~~~~~~~~~~~ -!!! error TS2412: Property '6' of type '() => string' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '6' of type '() => string' is not assignable to 'string' index type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/propertiesAndIndexersForNumericNames.errors.txt b/tests/baselines/reference/propertiesAndIndexersForNumericNames.errors.txt index f256cb0f4c18c..03f00bc63a4d7 100644 --- a/tests/baselines/reference/propertiesAndIndexersForNumericNames.errors.txt +++ b/tests/baselines/reference/propertiesAndIndexersForNumericNames.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(6,12): error TS2412: Property '"1"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(7,12): error TS2412: Property '"-1"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(8,12): error TS2412: Property '"-2.5"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(9,12): error TS2412: Property '"3.141592"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(10,12): error TS2412: Property '"1.2e-20"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(11,12): error TS2412: Property '"Infinity"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(12,12): error TS2412: Property '"-Infinity"' of type 'string' is not assignable to numeric index type 'number'. -tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(13,12): error TS2412: Property '"NaN"' of type 'string' is not assignable to numeric index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(6,12): error TS2411: Property '"1"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(7,12): error TS2411: Property '"-1"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(8,12): error TS2411: Property '"-2.5"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(9,12): error TS2411: Property '"3.141592"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(10,12): error TS2411: Property '"1.2e-20"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(11,12): error TS2411: Property '"Infinity"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(12,12): error TS2411: Property '"-Infinity"' of type 'string' is not assignable to 'number' index type 'number'. +tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(13,12): error TS2411: Property '"NaN"' of type 'string' is not assignable to 'number' index type 'number'. ==== tests/cases/compiler/propertiesAndIndexersForNumericNames.ts (8 errors) ==== @@ -16,28 +16,28 @@ tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(13,12): error TS241 // because their types are not compatible with the numeric indexer. public "1": string = "number"; // Error ~~~ -!!! error TS2412: Property '"1"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"1"' of type 'string' is not assignable to 'number' index type 'number'. public "-1": string = "negative number"; // Error ~~~~ -!!! error TS2412: Property '"-1"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"-1"' of type 'string' is not assignable to 'number' index type 'number'. public "-2.5": string = "negative number"; // Error ~~~~~~ -!!! error TS2412: Property '"-2.5"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"-2.5"' of type 'string' is not assignable to 'number' index type 'number'. public "3.141592": string = "pi-sitive number"; // Error ~~~~~~~~~~ -!!! error TS2412: Property '"3.141592"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"3.141592"' of type 'string' is not assignable to 'number' index type 'number'. public "1.2e-20": string = "really small number"; // Error ~~~~~~~~~ -!!! error TS2412: Property '"1.2e-20"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"1.2e-20"' of type 'string' is not assignable to 'number' index type 'number'. public "Infinity": string = "A gillion"; // Error ~~~~~~~~~~ -!!! error TS2412: Property '"Infinity"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"Infinity"' of type 'string' is not assignable to 'number' index type 'number'. public "-Infinity": string = "Negative-a-gillion"; // Error ~~~~~~~~~~~ -!!! error TS2412: Property '"-Infinity"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"-Infinity"' of type 'string' is not assignable to 'number' index type 'number'. public "NaN": string = "not a number"; // Error ~~~~~ -!!! error TS2412: Property '"NaN"' of type 'string' is not assignable to numeric index type 'number'. +!!! error TS2411: Property '"NaN"' of type 'string' is not assignable to 'number' index type 'number'. // These all have *partially* numeric names, // but should really be treated as plain string literals. diff --git a/tests/baselines/reference/staticIndexSignature3.errors.txt b/tests/baselines/reference/staticIndexSignature3.errors.txt index 4b57e0ab00d70..16d1af598bf8d 100644 --- a/tests/baselines/reference/staticIndexSignature3.errors.txt +++ b/tests/baselines/reference/staticIndexSignature3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(12,5): error TS2413: Numeric index type '1' is not assignable to string index type 'boolean'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(12,5): error TS2413: 'number' index type '1' is not assignable to 'string' index type 'boolean'. ==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts (1 errors) ==== @@ -15,7 +15,7 @@ tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(12 static readonly [s: string]: boolean static readonly [s: number]: 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2413: Numeric index type '1' is not assignable to string index type 'boolean'. +!!! error TS2413: 'number' index type '1' is not assignable to 'string' index type 'boolean'. } class DD extends D { diff --git a/tests/baselines/reference/staticIndexSignature7.errors.txt b/tests/baselines/reference/staticIndexSignature7.errors.txt index 79bb882745144..633f39f831faa 100644 --- a/tests/baselines/reference/staticIndexSignature7.errors.txt +++ b/tests/baselines/reference/staticIndexSignature7.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(3,12): error TS2411: Property 'x' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(7,12): error TS2411: Property 'foo' of type '() => void' is not assignable to string index type 'string'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(3,12): error TS2411: Property 'x' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(7,12): error TS2411: Property 'foo' of type '() => void' is not assignable to 'string' index type 'string'. ==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts (2 errors) ==== @@ -7,12 +7,12 @@ tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(7, static [index: string]: string; static x = 12; // Should error, incompatible with index signature ~ -!!! error TS2411: Property 'x' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'x' of type 'number' is not assignable to 'string' index type 'string'. } class Y { static [index: string]: string; static foo() {} // should error, incompatible with index signature ~~~ -!!! error TS2411: Property 'foo' of type '() => void' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo' of type '() => void' is not assignable to 'string' index type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/stringIndexerAndConstructor.errors.txt b/tests/baselines/reference/stringIndexerAndConstructor.errors.txt index 66122d93de952..069ff35bad2fe 100644 --- a/tests/baselines/reference/stringIndexerAndConstructor.errors.txt +++ b/tests/baselines/reference/stringIndexerAndConstructor.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/stringIndexerAndConstructor.ts(11,5): error TS2411: Property '""' of type 'string' is not assignable to string index type 'number'. -tests/cases/compiler/stringIndexerAndConstructor.ts(12,5): error TS2411: Property 'd' of type 'string' is not assignable to string index type 'number'. +tests/cases/compiler/stringIndexerAndConstructor.ts(11,5): error TS2411: Property '""' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/compiler/stringIndexerAndConstructor.ts(12,5): error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'number'. ==== tests/cases/compiler/stringIndexerAndConstructor.ts (2 errors) ==== @@ -15,8 +15,8 @@ tests/cases/compiler/stringIndexerAndConstructor.ts(12,5): error TS2411: Propert new (): boolean; "": string; ~~ -!!! error TS2411: Property '""' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property '""' of type 'string' is not assignable to 'string' index type 'number'. d: string; ~ -!!! error TS2411: Property 'd' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/stringIndexerAndConstructor1.errors.txt b/tests/baselines/reference/stringIndexerAndConstructor1.errors.txt index 28783924d2cf5..bb220d75a54f2 100644 --- a/tests/baselines/reference/stringIndexerAndConstructor1.errors.txt +++ b/tests/baselines/reference/stringIndexerAndConstructor1.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/stringIndexerAndConstructor1.ts(3,5): error TS2411: Property '""' of type 'string' is not assignable to string index type 'number'. +tests/cases/compiler/stringIndexerAndConstructor1.ts(3,5): error TS2411: Property '""' of type 'string' is not assignable to 'string' index type 'number'. ==== tests/cases/compiler/stringIndexerAndConstructor1.ts (1 errors) ==== @@ -6,5 +6,5 @@ tests/cases/compiler/stringIndexerAndConstructor1.ts(3,5): error TS2411: Propert [s: string]: number; "": string; ~~ -!!! error TS2411: Property '""' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property '""' of type 'string' is not assignable to 'string' index type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt index 00fc13f186eec..1d07fbfb4498b 100644 --- a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt +++ b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations.errors.txt @@ -1,27 +1,27 @@ -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(13,5): error TS2411: Property 'b' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(14,5): error TS2411: Property 'c' of type '() => {}' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(16,5): error TS2411: Property '"e"' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(18,5): error TS2411: Property '2.0' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(20,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(21,5): error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(13,5): error TS2411: Property 'b' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(14,5): error TS2411: Property 'c' of type '() => {}' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(16,5): error TS2411: Property '"e"' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(18,5): error TS2411: Property '2.0' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(20,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(21,5): error TS2411: Property 'f' of type 'MyString' is not assignable to 'string' index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(23,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(26,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(28,5): error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(28,5): error TS2411: Property 'foo' of type '() => string' is not assignable to 'string' index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(36,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(45,5): error TS2411: Property 'b' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(46,5): error TS2411: Property 'c' of type '() => {}' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(48,5): error TS2411: Property '"e"' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2411: Property '2.0' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(53,5): error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(55,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(56,5): error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(63,5): error TS2411: Property 'b' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(64,5): error TS2411: Property 'c' of type '() => {}' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(66,5): error TS2411: Property '"e"' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2411: Property '2.0' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(71,5): error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(73,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(74,5): error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(45,5): error TS2411: Property 'b' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(46,5): error TS2411: Property 'c' of type '() => {}' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(48,5): error TS2411: Property '"e"' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2411: Property '2.0' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(53,5): error TS2411: Property 'foo' of type '() => string' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(55,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(56,5): error TS2411: Property 'f' of type 'MyString' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(63,5): error TS2411: Property 'b' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(64,5): error TS2411: Property 'c' of type '() => {}' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(66,5): error TS2411: Property '"e"' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2411: Property '2.0' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(71,5): error TS2411: Property 'foo' of type '() => string' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(73,5): error TS2411: Property '"4.0"' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(74,5): error TS2411: Property 'f' of type 'MyString' is not assignable to 'string' index type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(80,5): error TS2322: Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(81,5): error TS2322: Type '() => void' is not assignable to type 'string'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations.ts(83,5): error TS2322: Type 'number' is not assignable to type 'string'. @@ -48,25 +48,25 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon a: string; // ok b: number; // error ~ -!!! error TS2411: Property 'b' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'b' of type 'number' is not assignable to 'string' index type 'string'. c: () => {} // error ~ -!!! error TS2411: Property 'c' of type '() => {}' is not assignable to string index type 'string'. +!!! error TS2411: Property 'c' of type '() => {}' is not assignable to 'string' index type 'string'. "d": string; // ok "e": number; // error ~~~ -!!! error TS2411: Property '"e"' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '"e"' of type 'number' is not assignable to 'string' index type 'string'. 1.0: string; // ok 2.0: number; // error ~~~ -!!! error TS2411: Property '2.0' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '2.0' of type 'number' is not assignable to 'string' index type 'string'. "3.0": string; // ok "4.0": number; // error ~~~~~ -!!! error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '"4.0"' of type 'number' is not assignable to 'string' index type 'string'. f: MyString; // error ~ -!!! error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. +!!! error TS2411: Property 'f' of type 'MyString' is not assignable to 'string' index type 'string'. get X() { // ok ~ @@ -79,7 +79,7 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon foo() { // error ~~~ -!!! error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo' of type '() => string' is not assignable to 'string' index type 'string'. return ''; } @@ -100,30 +100,30 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon a: string; // ok b: number; // error ~ -!!! error TS2411: Property 'b' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'b' of type 'number' is not assignable to 'string' index type 'string'. c: () => {} // error ~ -!!! error TS2411: Property 'c' of type '() => {}' is not assignable to string index type 'string'. +!!! error TS2411: Property 'c' of type '() => {}' is not assignable to 'string' index type 'string'. "d": string; // ok "e": number; // error ~~~ -!!! error TS2411: Property '"e"' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '"e"' of type 'number' is not assignable to 'string' index type 'string'. 1.0: string; // ok 2.0: number; // error ~~~ -!!! error TS2411: Property '2.0' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '2.0' of type 'number' is not assignable to 'string' index type 'string'. (): string; // ok (x): number // ok foo(): string; // error ~~~~~~~~~~~~~~ -!!! error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo' of type '() => string' is not assignable to 'string' index type 'string'. "3.0": string; // ok "4.0": number; // error ~~~~~ -!!! error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '"4.0"' of type 'number' is not assignable to 'string' index type 'string'. f: MyString; // error ~ -!!! error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. +!!! error TS2411: Property 'f' of type 'MyString' is not assignable to 'string' index type 'string'. } var a: { @@ -132,30 +132,30 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon a: string; // ok b: number; // error ~ -!!! error TS2411: Property 'b' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'b' of type 'number' is not assignable to 'string' index type 'string'. c: () => {} // error ~ -!!! error TS2411: Property 'c' of type '() => {}' is not assignable to string index type 'string'. +!!! error TS2411: Property 'c' of type '() => {}' is not assignable to 'string' index type 'string'. "d": string; // ok "e": number; // error ~~~ -!!! error TS2411: Property '"e"' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '"e"' of type 'number' is not assignable to 'string' index type 'string'. 1.0: string; // ok 2.0: number; // error ~~~ -!!! error TS2411: Property '2.0' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '2.0' of type 'number' is not assignable to 'string' index type 'string'. (): string; // ok (x): number // ok foo(): string; // error ~~~~~~~~~~~~~~ -!!! error TS2411: Property 'foo' of type '() => string' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo' of type '() => string' is not assignable to 'string' index type 'string'. "3.0": string; // ok "4.0": number; // error ~~~~~ -!!! error TS2411: Property '"4.0"' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property '"4.0"' of type 'number' is not assignable to 'string' index type 'string'. f: MyString; // error ~ -!!! error TS2411: Property 'f' of type 'MyString' is not assignable to string index type 'string'. +!!! error TS2411: Property 'f' of type 'MyString' is not assignable to 'string' index type 'string'. } // error diff --git a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt index 8923b04d51fc7..2d6cbf094badb 100644 --- a/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt +++ b/tests/baselines/reference/stringIndexerConstrainsPropertyDeclarations2.errors.txt @@ -1,9 +1,9 @@ -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(15,5): error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(23,5): error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(24,5): error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(31,5): error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(32,5): error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(15,5): error TS2411: Property 'c' of type 'number' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(23,5): error TS2411: Property 'c' of type 'number' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(24,5): error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(31,5): error TS2411: Property 'c' of type 'number' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(32,5): error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(37,8): error TS2741: Property 'foo' is missing in type 'typeof A' but required in type 'A'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerConstrainsPropertyDeclarations2.ts(38,8): error TS2741: Property 'foo' is missing in type 'typeof B' but required in type 'A'. @@ -25,10 +25,10 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon b: B; // ok c: number; // error ~ -!!! error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. +!!! error TS2411: Property 'c' of type 'number' is not assignable to 'string' index type 'A'. d: string; // error ~ -!!! error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. +!!! error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'A'. } interface Foo2 { @@ -37,10 +37,10 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon b: B; // ok c: number; // error ~ -!!! error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. +!!! error TS2411: Property 'c' of type 'number' is not assignable to 'string' index type 'A'. d: string; // error ~ -!!! error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. +!!! error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'A'. } var a: { @@ -49,10 +49,10 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/stringIndexerCon b: B; // ok c: number; // error ~ -!!! error TS2411: Property 'c' of type 'number' is not assignable to string index type 'A'. +!!! error TS2411: Property 'c' of type 'number' is not assignable to 'string' index type 'A'. d: string; // error ~ -!!! error TS2411: Property 'd' of type 'string' is not assignable to string index type 'A'. +!!! error TS2411: Property 'd' of type 'string' is not assignable to 'string' index type 'A'. }; // error diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt index 8c8a65f9f7c34..47d37449c0925 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints.errors.txt @@ -1,40 +1,40 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(19,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(50,5): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(67,5): error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(72,5): error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(112,5): error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. Type 'U' is not assignable to type 'T'. 'U' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(134,5): error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'T'. 'V' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(139,5): error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. Type 'V' is not assignable to type 'U'. 'V' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2411: Property 'foo' of type 'Date' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(156,5): error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'T'. 'Date' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2411: Property 'foo' of type 'Date' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(161,5): error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'U'. 'Date' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2411: Property 'foo' of type 'Date' is not assignable to 'string' index type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints.ts(166,5): error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. Type 'Date' is not assignable to type 'V'. 'Date' is assignable to the constraint of type 'V', but 'V' could be instantiated with a different subtype of constraint 'Date'. @@ -61,7 +61,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -98,7 +98,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -121,7 +121,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D11' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'T'. @@ -132,7 +132,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D12' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'U'. @@ -178,7 +178,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D19' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -206,7 +206,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D23' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'T'. @@ -217,7 +217,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D24' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'V' is not assignable to type 'U'. @@ -240,7 +240,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: Date; // error ~~~ -!!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'Date' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D27' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'T'. @@ -251,7 +251,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: Date; // error ~~~ -!!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'Date' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D28' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'U'. @@ -262,7 +262,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: Date; // error ~~~ -!!! error TS2411: Property 'foo' of type 'Date' is not assignable to string index type 'V'. +!!! error TS2411: Property 'foo' of type 'Date' is not assignable to 'string' index type 'V'. ~~~ !!! error TS2416: Property 'foo' in type 'D29' is not assignable to the same property in base type 'C3'. !!! error TS2416: Type 'Date' is not assignable to type 'V'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt index 0f63d2741304a..ece15e0e45196 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithConstraints4.errors.txt @@ -1,19 +1,19 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'Foo'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(47,5): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(57,5): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. Type 'U' is not assignable to type 'T'. 'U' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(62,5): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(67,5): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'Foo'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithConstraints4.ts(77,5): error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. Type 'V' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'V'. @@ -68,7 +68,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: Foo; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'Foo'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'Foo'. ~~~ !!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. @@ -83,7 +83,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U; // error ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -94,7 +94,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'T'. @@ -105,7 +105,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T; // error ~~~ -!!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'T' is not assignable to type 'U'. @@ -121,7 +121,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V; // error ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D9' is not assignable to the same property in base type 'B1'. !!! error TS2416: Type 'V' is not assignable to type 'U'. diff --git a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt index f7b626f3ae73f..97f08bcda3571 100644 --- a/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt +++ b/tests/baselines/reference/subtypesOfTypeParameterWithRecursiveConstraints.errors.txt @@ -1,24 +1,24 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(68,9): error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(73,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. Type 'V' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(78,9): error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. Type 'T' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(88,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. Type 'V' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(93,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. Type 'T' is not assignable to type 'V'. 'V' could be instantiated with an arbitrary type which could be unrelated to 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(98,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. Type 'U' is not assignable to type 'V'. 'V' could be instantiated with an arbitrary type which could be unrelated to 'U'. @@ -27,32 +27,32 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(120,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(120,9): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(125,9): error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. Type 'V' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'V' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(130,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(130,9): error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(135,9): error TS2416: Property 'foo' in type 'D5' is not assignable to the same property in base type 'Base2'. Type 'U' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'T' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(140,9): error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. Type 'V' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'V' is not assignable to type 'U'. 'U' could be instantiated with an arbitrary type which could be unrelated to 'V'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(145,9): error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. Type 'T' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. Type 'U' is not assignable to type 'V'. 'V' could be instantiated with an arbitrary type which could be unrelated to 'U'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'V'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfTypeParameterWithRecursiveConstraints.ts(150,9): error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. Type 'U' is not assignable to type 'Foo'. Type 'Foo' is not assignable to type 'Foo'. @@ -130,7 +130,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D2' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'T'. @@ -141,7 +141,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: V ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'V' is not assignable to type 'T'. @@ -152,7 +152,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T ~~~ -!!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D4' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'T' is not assignable to type 'U'. @@ -168,7 +168,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'V' is not assignable to type 'U'. @@ -179,7 +179,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: T ~~~ -!!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. +!!! error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'V'. ~~~ !!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'T' is not assignable to type 'V'. @@ -190,7 +190,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: U ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'V'. ~~~ !!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base'. !!! error TS2416: Type 'U' is not assignable to type 'V'. @@ -224,14 +224,14 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: T; foo: U ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'T'. } class D3, U extends Foo, V extends Foo> extends Base2 { [x: string]: T; foo: V ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'T'. ~~~ !!! error TS2416: Property 'foo' in type 'D3' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. @@ -244,7 +244,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: T ~~~ -!!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'U'. } class D5, U extends Foo, V extends Foo> extends Base2 { @@ -262,7 +262,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: U; foo: V ~~~ -!!! error TS2411: Property 'foo' of type 'V' is not assignable to string index type 'U'. +!!! error TS2411: Property 'foo' of type 'V' is not assignable to 'string' index type 'U'. ~~~ !!! error TS2416: Property 'foo' in type 'D6' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'V' is not assignable to type 'Foo'. @@ -275,7 +275,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: T ~~~ -!!! error TS2411: Property 'foo' of type 'T' is not assignable to string index type 'V'. +!!! error TS2411: Property 'foo' of type 'T' is not assignable to 'string' index type 'V'. ~~~ !!! error TS2416: Property 'foo' in type 'D7' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'T' is not assignable to type 'Foo'. @@ -288,7 +288,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf [x: string]: V; foo: U ~~~ -!!! error TS2411: Property 'foo' of type 'U' is not assignable to string index type 'V'. +!!! error TS2411: Property 'foo' of type 'U' is not assignable to 'string' index type 'V'. ~~~ !!! error TS2416: Property 'foo' in type 'D8' is not assignable to the same property in base type 'Base2'. !!! error TS2416: Type 'U' is not assignable to type 'Foo'. diff --git a/tests/baselines/reference/subtypesOfUnion.errors.txt b/tests/baselines/reference/subtypesOfUnion.errors.txt index aa30d24f5bdc3..400f3cbe44e99 100644 --- a/tests/baselines/reference/subtypesOfUnion.errors.txt +++ b/tests/baselines/reference/subtypesOfUnion.errors.txt @@ -1,32 +1,32 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(16,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(18,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(19,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(20,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(21,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(22,5): error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(23,5): error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(24,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(25,5): error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(26,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(27,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(28,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(29,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(30,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'string | number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(35,5): error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(37,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(39,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(40,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(41,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(42,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(43,5): error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(44,5): error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(45,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(46,5): error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(47,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(48,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(49,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(50,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(51,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(16,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(18,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(19,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(20,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(21,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(22,5): error TS2411: Property 'foo10' of type 'A' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(23,5): error TS2411: Property 'foo11' of type 'A2' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(24,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(25,5): error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(26,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(27,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(28,5): error TS2411: Property 'foo16' of type 'T' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(29,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(30,5): error TS2411: Property 'foo18' of type '{}' is not assignable to 'string' index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(35,5): error TS2411: Property 'foo2' of type 'string' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(37,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(39,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(40,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(41,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(42,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(43,5): error TS2411: Property 'foo10' of type 'A' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(44,5): error TS2411: Property 'foo11' of type 'A2' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(45,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(46,5): error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(47,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(48,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(49,5): error TS2411: Property 'foo16' of type 'T' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(50,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(51,5): error TS2411: Property 'foo18' of type '{}' is not assignable to 'string' index type 'number'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts (29 errors) ==== @@ -47,96 +47,96 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOf foo3: number; // ok foo4: boolean; // error ~~~~ -!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to 'string' index type 'string | number'. foo5: E; // ok - subtype of number foo6: Date; // error ~~~~ -!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to 'string' index type 'string | number'. foo7: RegExp; // error ~~~~ -!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to 'string' index type 'string | number'. foo8: { bar: number }; // error ~~~~ -!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to 'string' index type 'string | number'. foo9: I8; // error ~~~~ -!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to 'string' index type 'string | number'. foo10: A; // error ~~~~~ -!!! error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo10' of type 'A' is not assignable to 'string' index type 'string | number'. foo11: A2; // error ~~~~~ -!!! error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo11' of type 'A2' is not assignable to 'string' index type 'string | number'. foo12: (x) => number; //error ~~~~~ -!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to 'string' index type 'string | number'. foo13: (x: T) => T; // error ~~~~~ -!!! error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to 'string' index type 'string | number'. foo14: typeof f; // error ~~~~~ -!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to 'string' index type 'string | number'. foo15: typeof c; // error ~~~~~ -!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to 'string' index type 'string | number'. foo16: T; // error ~~~~~ -!!! error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo16' of type 'T' is not assignable to 'string' index type 'string | number'. foo17: Object; // error ~~~~~ -!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to 'string' index type 'string | number'. foo18: {}; // error ~~~~~ -!!! error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'string | number'. +!!! error TS2411: Property 'foo18' of type '{}' is not assignable to 'string' index type 'string | number'. } interface I2 { [x: string]: E | number; foo: any; // ok foo2: string; // error ~~~~ -!!! error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo2' of type 'string' is not assignable to 'string' index type 'number'. foo3: number; // ok foo4: boolean; // error ~~~~ -!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to 'string' index type 'number'. foo5: E; // ok foo6: Date; // error ~~~~ -!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to 'string' index type 'number'. foo7: RegExp; // error ~~~~ -!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to 'string' index type 'number'. foo8: { bar: number }; // error ~~~~ -!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to 'string' index type 'number'. foo9: I8; // error ~~~~ -!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to 'string' index type 'number'. foo10: A; // error ~~~~~ -!!! error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo10' of type 'A' is not assignable to 'string' index type 'number'. foo11: A2; // error ~~~~~ -!!! error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo11' of type 'A2' is not assignable to 'string' index type 'number'. foo12: (x) => number; //error ~~~~~ -!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to 'string' index type 'number'. foo13: (x: T) => T; // error ~~~~~ -!!! error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to 'string' index type 'number'. foo14: typeof f; // error ~~~~~ -!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to 'string' index type 'number'. foo15: typeof c; // error ~~~~~ -!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to 'string' index type 'number'. foo16: T; // error ~~~~~ -!!! error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo16' of type 'T' is not assignable to 'string' index type 'number'. foo17: Object; // error ~~~~~ -!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to 'string' index type 'number'. foo18: {}; // error ~~~~~ -!!! error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo18' of type '{}' is not assignable to 'string' index type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/symbolProperty17.errors.txt b/tests/baselines/reference/symbolProperty17.errors.txt index 44e34bb7ec0e1..4b6ee88ffd214 100644 --- a/tests/baselines/reference/symbolProperty17.errors.txt +++ b/tests/baselines/reference/symbolProperty17.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/Symbols/symbolProperty17.ts(2,5): error TS2412: Property '[Symbol.iterator]' of type 'number' is not assignable to numeric index type 'string'. +tests/cases/conformance/es6/Symbols/symbolProperty17.ts(2,5): error TS2411: Property '[Symbol.iterator]' of type 'number' is not assignable to 'symbol' index type 'string'. ==== tests/cases/conformance/es6/Symbols/symbolProperty17.ts (1 errors) ==== interface I { [Symbol.iterator]: number; ~~~~~~~~~~~~~~~~~ -!!! error TS2412: Property '[Symbol.iterator]' of type 'number' is not assignable to numeric index type 'string'. +!!! error TS2411: Property '[Symbol.iterator]' of type 'number' is not assignable to 'symbol' index type 'string'. [s: symbol]: string; "__@iterator": string; } diff --git a/tests/baselines/reference/symbolProperty30.errors.txt b/tests/baselines/reference/symbolProperty30.errors.txt index 1993f25412e90..97ae1d8f60076 100644 --- a/tests/baselines/reference/symbolProperty30.errors.txt +++ b/tests/baselines/reference/symbolProperty30.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/Symbols/symbolProperty30.ts(2,5): error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. +tests/cases/conformance/es6/Symbols/symbolProperty30.ts(2,5): error TS2411: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to 'symbol' index type '() => { x: number; }'. ==== tests/cases/conformance/es6/Symbols/symbolProperty30.ts (1 errors) ==== class C1 { [Symbol.toStringTag]() { ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. +!!! error TS2411: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to 'symbol' index type '() => { x: number; }'. return { x: "" }; } [s: symbol]: () => { x: number }; diff --git a/tests/baselines/reference/symbolProperty32.errors.txt b/tests/baselines/reference/symbolProperty32.errors.txt index 369371df18eb6..9bacef82a7c7d 100644 --- a/tests/baselines/reference/symbolProperty32.errors.txt +++ b/tests/baselines/reference/symbolProperty32.errors.txt @@ -1,11 +1,11 @@ -tests/cases/conformance/es6/Symbols/symbolProperty32.ts(2,5): error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. +tests/cases/conformance/es6/Symbols/symbolProperty32.ts(2,5): error TS2411: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to 'symbol' index type '() => { x: number; }'. ==== tests/cases/conformance/es6/Symbols/symbolProperty32.ts (1 errors) ==== class C1 { [Symbol.toStringTag]() { ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. +!!! error TS2411: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to 'symbol' index type '() => { x: number; }'. return { x: "" }; } } diff --git a/tests/baselines/reference/symbolProperty34.errors.txt b/tests/baselines/reference/symbolProperty34.errors.txt index e7e2c858cd886..e1fe289ce70a0 100644 --- a/tests/baselines/reference/symbolProperty34.errors.txt +++ b/tests/baselines/reference/symbolProperty34.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/Symbols/symbolProperty34.ts(1,18): error TS2449: Class 'C2' used before its declaration. -tests/cases/conformance/es6/Symbols/symbolProperty34.ts(2,5): error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. +tests/cases/conformance/es6/Symbols/symbolProperty34.ts(2,5): error TS2411: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to 'symbol' index type '() => { x: number; }'. ==== tests/cases/conformance/es6/Symbols/symbolProperty34.ts (2 errors) ==== @@ -9,7 +9,7 @@ tests/cases/conformance/es6/Symbols/symbolProperty34.ts(2,5): error TS2412: Prop !!! related TS2728 tests/cases/conformance/es6/Symbols/symbolProperty34.ts:6:7: 'C2' is declared here. [Symbol.toStringTag]() { ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2412: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to numeric index type '() => { x: number; }'. +!!! error TS2411: Property '[Symbol.toStringTag]' of type '() => { x: string; }' is not assignable to 'symbol' index type '() => { x: number; }'. return { x: "" }; } } diff --git a/tests/baselines/reference/typeName1.errors.txt b/tests/baselines/reference/typeName1.errors.txt index 28c88a45ca0d6..71a804d67ba8d 100644 --- a/tests/baselines/reference/typeName1.errors.txt +++ b/tests/baselines/reference/typeName1.errors.txt @@ -6,12 +6,12 @@ tests/cases/compiler/typeName1.ts(13,5): error TS2322: Type 'number' is not assi tests/cases/compiler/typeName1.ts(14,5): error TS2322: Type 'number' is not assignable to type '{ z: number; f: { (n: number): string; (s: string): number; }; }'. tests/cases/compiler/typeName1.ts(15,5): error TS2322: Type 'number' is not assignable to type '(s: string) => boolean'. tests/cases/compiler/typeName1.ts(16,5): error TS2322: Type 'number' is not assignable to type '{ (): boolean; [s: string]: { x: any; y: any; }; [n: number]: { x: any; y: any; }; z: I; }'. -tests/cases/compiler/typeName1.ts(16,10): error TS2411: Property 'z' of type 'I' is not assignable to string index type '{ x: any; y: any; }'. +tests/cases/compiler/typeName1.ts(16,10): error TS2411: Property 'z' of type 'I' is not assignable to 'string' index type '{ x: any; y: any; }'. tests/cases/compiler/typeName1.ts(17,5): error TS2322: Type 'number' is not assignable to type 'I'. tests/cases/compiler/typeName1.ts(18,5): error TS2322: Type 'number' is not assignable to type 'I[][][][]'. tests/cases/compiler/typeName1.ts(19,5): error TS2322: Type 'number' is not assignable to type '{ z: I; x: boolean; }[][]'. tests/cases/compiler/typeName1.ts(20,5): error TS2322: Type 'number' is not assignable to type '{ z: I; x: boolean; y: (s: string) => boolean; w: { (): boolean; [s: string]: { x: any; y: any; }; [n: number]: { x: any; y: any; }; z: I; }; }[][]'. -tests/cases/compiler/typeName1.ts(20,50): error TS2411: Property 'z' of type 'I' is not assignable to string index type '{ x: any; y: any; }'. +tests/cases/compiler/typeName1.ts(20,50): error TS2411: Property 'z' of type 'I' is not assignable to 'string' index type '{ x: any; y: any; }'. tests/cases/compiler/typeName1.ts(21,5): error TS2322: Type 'number' is not assignable to type '{ (): {}; new (): number; new (n: number): number; x: string; w: { y: number; }; }'. tests/cases/compiler/typeName1.ts(22,5): error TS2322: Type 'number' is not assignable to type '{ (): string; f(x: number): boolean; p: any; q: any; }'. tests/cases/compiler/typeName1.ts(23,5): error TS2322: Type 'typeof C' is not assignable to type 'number'. @@ -51,7 +51,7 @@ tests/cases/compiler/typeName1.ts(23,5): error TS2322: Type 'typeof C' is not as ~~ !!! error TS2322: Type 'number' is not assignable to type '{ (): boolean; [s: string]: { x: any; y: any; }; [n: number]: { x: any; y: any; }; z: I; }'. ~ -!!! error TS2411: Property 'z' of type 'I' is not assignable to string index type '{ x: any; y: any; }'. +!!! error TS2411: Property 'z' of type 'I' is not assignable to 'string' index type '{ x: any; y: any; }'. var x9:I=3; ~~ !!! error TS2322: Type 'number' is not assignable to type 'I'. @@ -65,7 +65,7 @@ tests/cases/compiler/typeName1.ts(23,5): error TS2322: Type 'typeof C' is not as ~~~ !!! error TS2322: Type 'number' is not assignable to type '{ z: I; x: boolean; y: (s: string) => boolean; w: { (): boolean; [s: string]: { x: any; y: any; }; [n: number]: { x: any; y: any; }; z: I; }; }[][]'. ~ -!!! error TS2411: Property 'z' of type 'I' is not assignable to string index type '{ x: any; y: any; }'. +!!! error TS2411: Property 'z' of type 'I' is not assignable to 'string' index type '{ x: any; y: any; }'. var x13:{ new(): number; new(n:number):number; x: string; w: {y: number;}; (): {}; } = 3; ~~~ !!! error TS2322: Type 'number' is not assignable to type '{ (): {}; new (): number; new (n: number): number; x: string; w: { y: number; }; }'. diff --git a/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt b/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt index da2b98f75bb1f..eca747eccceea 100644 --- a/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt +++ b/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt @@ -1,33 +1,33 @@ -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(15,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(21,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'string'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(22,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'string'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(28,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'boolean'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(29,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'boolean'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(35,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(36,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'Date'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(42,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'RegExp'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(43,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'RegExp'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(49,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '{ bar: number; }'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(50,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '{ bar: number; }'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(56,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number[]'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(57,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'number[]'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(63,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'I8'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(64,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'I8'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(70,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(71,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(77,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A2'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(78,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A2'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(84,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: any) => number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(85,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '(x: any) => number'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(91,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: T) => T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(92,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '(x: T) => T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(99,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'E2'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(110,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof f'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(111,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof f'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(121,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof c'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(122,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof c'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(128,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'T'. -tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(129,5): error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(15,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(21,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(22,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'string'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(28,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'boolean'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(29,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'boolean'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(35,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'Date'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(36,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'Date'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(42,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'RegExp'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(43,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'RegExp'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(49,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type '{ bar: number; }'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(50,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type '{ bar: number; }'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(56,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'number[]'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(57,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'number[]'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(63,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'I8'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(64,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'I8'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(70,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(71,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'A'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(77,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'A2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(78,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'A2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(84,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type '(x: any) => number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(85,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type '(x: any) => number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(91,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(92,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(99,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'E2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(110,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'typeof f'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(111,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'typeof f'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(121,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'typeof c'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(122,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'typeof c'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(128,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(129,5): error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'T'. ==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts (30 errors) ==== @@ -47,7 +47,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty // S is union type and each constituent type of S is a subtype of T foo: string | number; // error string is not subtype of number ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'number'. foo2: e | number; // ok e and number both subtype of number } @@ -55,10 +55,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: string; foo: string | number; // error numer is not subtype of string ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'string'. foo2: e | number; // error e and number both not subtype of string ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'string'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'string'. } // error cases @@ -66,10 +66,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: boolean; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'boolean'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'boolean'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'boolean'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'boolean'. } @@ -77,10 +77,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: Date; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'Date'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'Date'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'Date'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'Date'. } @@ -88,10 +88,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: RegExp; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'RegExp'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'RegExp'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'RegExp'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'RegExp'. } @@ -99,10 +99,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: { bar: number }; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '{ bar: number; }'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type '{ bar: number; }'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '{ bar: number; }'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type '{ bar: number; }'. } @@ -110,10 +110,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: number[]; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number[]'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'number[]'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'number[]'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'number[]'. } @@ -121,10 +121,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: I8; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'I8'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'I8'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'I8'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'I8'. } class A { foo: number; } @@ -132,10 +132,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: A; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'A'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'A'. } class A2 { foo: T; } @@ -143,10 +143,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: A2; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A2'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'A2'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'A2'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'A2'. } @@ -154,10 +154,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: (x) => number; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: any) => number'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type '(x: any) => number'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '(x: any) => number'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type '(x: any) => number'. } @@ -165,10 +165,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: (x: T) => T; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: T) => T'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type '(x: T) => T'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type '(x: T) => T'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type '(x: T) => T'. } @@ -177,7 +177,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: E2; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'E2'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'E2'. foo2: e | number; } @@ -190,10 +190,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: typeof f; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof f'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'typeof f'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof f'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'typeof f'. } @@ -205,10 +205,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: typeof c; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof c'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'typeof c'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'typeof c'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'typeof c'. } @@ -216,10 +216,10 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubty [x: string]: T; foo: string | number; ~~~ -!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to 'string' index type 'T'. foo2: e | number; ~~~~ -!!! error TS2411: Property 'foo2' of type 'number' is not assignable to string index type 'T'. +!!! error TS2411: Property 'foo2' of type 'number' is not assignable to 'string' index type 'T'. } interface I19 { From 135e181630d69f1fc82c028f6d053dab46d3f224 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Jun 2021 11:20:12 -0700 Subject: [PATCH 25/56] Update type inference from index signatures --- src/compiler/checker.ts | 58 +++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index afdf0581221e7..fd30a1c821d77 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12002,25 +12002,6 @@ namespace ts { return info1 ? info2 ? [info1, info2] : [info1] : info2 ? [info2] : emptyArray; } - function getImplicitIndexTypeOfType(type: Type, keyType: Type): Type | undefined { - if (isObjectTypeWithInferableIndex(type)) { - const propTypes: Type[] = []; - for (const prop of getPropertiesOfType(type)) { - if (keyType === stringType || isNumericLiteralName(prop.escapedName)) { - const propType = getTypeOfSymbol(prop); - propTypes.push(prop.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType); - } - } - if (keyType === stringType) { - append(propTypes, getIndexTypeOfType(type, numberType)); - } - if (propTypes.length) { - return getUnionType(propTypes); - } - } - return undefined; - } - function isApplicableIndexType(source: Type, target: Type) { // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index // signature applies to types assignable to 'number' and numeric string literal types. @@ -21709,21 +21690,30 @@ namespace ts { function inferFromIndexTypes(source: Type, target: Type) { // Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0; - const targetStringIndexType = getIndexTypeOfType(target, stringType); - if (targetStringIndexType) { - const sourceIndexType = getIndexTypeOfType(source, stringType) || - getImplicitIndexTypeOfType(source, stringType); - if (sourceIndexType) { - inferWithPriority(sourceIndexType, targetStringIndexType, priority); - } - } - const targetNumberIndexType = getIndexTypeOfType(target, numberType); - if (targetNumberIndexType) { - const sourceIndexType = getIndexTypeOfType(source, numberType) || - getIndexTypeOfType(source, stringType) || - getImplicitIndexTypeOfType(source, numberType); - if (sourceIndexType) { - inferWithPriority(sourceIndexType, targetNumberIndexType, priority); + const indexInfos = getIndexInfosOfType(target); + if (isObjectTypeWithInferableIndex(source)) { + for (const targetInfo of indexInfos) { + const propTypes: Type[] = []; + for (const prop of getPropertiesOfType(source)) { + if (isApplicableIndexType(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), targetInfo.keyType)) { + const propType = getTypeOfSymbol(prop); + propTypes.push(prop.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType); + } + } + for (const info of getIndexInfosOfType(source)) { + if (isApplicableIndexType(info.keyType, targetInfo.keyType)) { + propTypes.push(info.type); + } + } + if (propTypes.length) { + inferWithPriority(getUnionType(propTypes), targetInfo.type, priority); + } + } + } + for (const targetInfo of indexInfos) { + const sourceInfo = getApplicableIndexInfo(source, targetInfo.keyType); + if (sourceInfo) { + inferWithPriority(sourceInfo.type, targetInfo.type, priority); } } } From 0c27c9cb32ec702b6a3621ae1efe554277d06cbd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Jun 2021 12:06:06 -0700 Subject: [PATCH 26/56] Update isKnownProperty --- src/compiler/checker.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fd30a1c821d77..c11a1c92bea5e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26961,9 +26961,8 @@ namespace ts { */ function isKnownProperty(targetType: Type, name: __String, isComparingJsxAttributes: boolean): boolean { if (targetType.flags & TypeFlags.Object) { - if (getIndexInfoOfStructuredType(targetType, stringType) || - getIndexInfoOfStructuredType(targetType, numberType) && isNumericLiteralName(name) || - getPropertyOfObjectType(targetType, name) || + if (getPropertyOfObjectType(targetType, name) || + getApplicableIndexInfoForName(targetType, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. return true; From b8ac0932bfde984ec00a0a917ff19e73bd7d2664 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Jun 2021 07:51:22 -0700 Subject: [PATCH 27/56] Update contextual typing based on index signatures --- src/compiler/checker.ts | 99 +++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c11a1c92bea5e..b766514a50672 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11966,59 +11966,15 @@ namespace ts { return getSignaturesOfStructuredType(getReducedApparentType(type), kind); } - function getIndexInfosOfStructuredType(type: Type): readonly IndexInfo[] { - if (type.flags & TypeFlags.StructuredType) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); - return resolved.indexInfos; - } - return emptyArray; - } - function findIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) { return find(indexInfos, info => info.keyType === keyType); } - function getIndexInfoOfStructuredType(type: Type, keyType: Type): IndexInfo | undefined { - return findIndexInfo(getIndexInfosOfStructuredType(type), keyType); - } - - function getIndexInfosOfType(type: Type): readonly IndexInfo[] { - return getIndexInfosOfStructuredType(getReducedApparentType(type)); - } - - // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and - // maps primitive types and type parameters are to their apparent types. - function getIndexInfoOfType(type: Type, keyType: Type): IndexInfo | undefined { - return getIndexInfoOfStructuredType(getReducedApparentType(type), keyType); - } - - // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and - // maps primitive types and type parameters are to their apparent types. - function getIndexTypeOfType(type: Type, keyType: Type): Type | undefined { - return getIndexInfoOfStructuredType(getReducedApparentType(type), keyType)?.type; - } - - function createIndexInfoArray(info1: IndexInfo | undefined, info2: IndexInfo | undefined) { - return info1 ? info2 ? [info1, info2] : [info1] : info2 ? [info2] : emptyArray; - } - - function isApplicableIndexType(source: Type, target: Type) { - // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index - // signature applies to types assignable to 'number' and numeric string literal types. - return isTypeAssignableTo(source, target) || - target === stringType && isTypeAssignableTo(source, numberType) || - target === numberType && source.flags & TypeFlags.StringLiteral && isNumericLiteralName((source as StringLiteralType).value); - } - - function getApplicableIndexInfos(type: Type, keyType: Type): IndexInfo[] { - return getIndexInfosOfType(type).filter(info => isApplicableIndexType(keyType, info.keyType)); - } - - function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { + function findApplicableIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) { let stringIndexInfo: IndexInfo | undefined; let applicableInfo: IndexInfo | undefined; let applicableInfos: IndexInfo[] | undefined; - for (const info of getIndexInfosOfType(type)) { + for (const info of indexInfos) { if (info.keyType === stringType) { stringIndexInfo = info; } @@ -12041,6 +11997,46 @@ namespace ts { undefined; } + function isApplicableIndexType(source: Type, target: Type) { + // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index + // signature applies to types assignable to 'number' and numeric string literal types. + return isTypeAssignableTo(source, target) || + target === stringType && isTypeAssignableTo(source, numberType) || + target === numberType && source.flags & TypeFlags.StringLiteral && isNumericLiteralName((source as StringLiteralType).value); + } + + function getIndexInfosOfStructuredType(type: Type): readonly IndexInfo[] { + if (type.flags & TypeFlags.StructuredType) { + const resolved = resolveStructuredTypeMembers(type as ObjectType); + return resolved.indexInfos; + } + return emptyArray; + } + + function getIndexInfosOfType(type: Type): readonly IndexInfo[] { + return getIndexInfosOfStructuredType(getReducedApparentType(type)); + } + + // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and + // maps primitive types and type parameters are to their apparent types. + function getIndexInfoOfType(type: Type, keyType: Type): IndexInfo | undefined { + return findIndexInfo(getIndexInfosOfType(type), keyType); + } + + // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and + // maps primitive types and type parameters are to their apparent types. + function getIndexTypeOfType(type: Type, keyType: Type): Type | undefined { + return getIndexInfoOfType(type, keyType)?.type; + } + + function getApplicableIndexInfos(type: Type, keyType: Type): IndexInfo[] { + return getIndexInfosOfType(type).filter(info => isApplicableIndexType(keyType, info.keyType)); + } + + function getApplicableIndexInfo(type: Type, keyType: Type): IndexInfo | undefined { + return findApplicableIndexInfo(getIndexInfosOfType(type), keyType); + } + function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined { return getApplicableIndexInfo(type, getLiteralType(unescapeLeadingUnderscores(name))); } @@ -25328,15 +25324,14 @@ namespace ts { return restType; } } - return isNumericLiteralName(name) && getIndexTypeOfContextualType(t, numberType) || - getIndexTypeOfContextualType(t, stringType); + return getIndexTypeOfContextualType(type, getLiteralType(unescapeLeadingUnderscores(name))); } return undefined; }, /*noReductions*/ true); } function getIndexTypeOfContextualType(type: Type, keyType: Type) { - return mapType(type, t => getIndexInfoOfStructuredType(t, keyType)?.type, /*noReductions*/ true); + return mapType(type, t => findApplicableIndexInfo(getIndexInfosOfStructuredType(t), keyType)?.type, /*noReductions*/ true); } // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of @@ -25369,8 +25364,7 @@ namespace ts { return propertyType; } } - return isNumericName(element.name!) && getIndexTypeOfContextualType(type, numberType) || - getIndexTypeOfContextualType(type, stringType); + return element.name && getIndexTypeOfContextualType(type, getLiteralTypeFromPropertyName(element.name)); } return undefined; } @@ -26352,7 +26346,8 @@ namespace ts { function createObjectLiteralType() { const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType) : undefined; const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType) : undefined; - const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, createIndexInfoArray(stringIndexInfo, numberIndexInfo)); + const indexInfos = stringIndexInfo ? numberIndexInfo ? [stringIndexInfo, numberIndexInfo] : [stringIndexInfo] : numberIndexInfo ? [numberIndexInfo] : emptyArray; + const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, indexInfos); result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; if (isJSObjectLiteral) { result.objectFlags |= ObjectFlags.JSLiteral; From b2a014c19792c430fb4404df5baec0998d926ba2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Jun 2021 07:52:13 -0700 Subject: [PATCH 28/56] Accept new baselines --- tests/baselines/reference/variadicTuples1.errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index b917aa585d2a3..87747d4956a18 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -33,7 +33,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. - Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. + Type '"2"' is not assignable to type '"0" | "1" | keyof T[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number | undefined'. tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. Type at position 0 in source is not compatible with type at position 0 in target. @@ -298,7 +298,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Typ k3 = '2'; // Error ~~ !!! error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. -!!! error TS2322: Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. +!!! error TS2322: Type '"2"' is not assignable to type '"0" | "1" | keyof T[]'. } // Inference between variadic tuple types From ab96d547060aaa3f34d2d014b89c00258fa3f071 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Jun 2021 11:36:40 -0700 Subject: [PATCH 29/56] Support union types in index signature declarations --- src/compiler/checker.ts | 40 +++++++------------ src/compiler/diagnosticMessages.json | 6 +-- src/compiler/symbolWalker.ts | 1 + .../codefixes/convertToMappedObjectType.ts | 2 +- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b766514a50672..b5c240fa69c53 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11971,6 +11971,7 @@ namespace ts { } function findApplicableIndexInfo(indexInfos: readonly IndexInfo[], keyType: Type) { + // Index signatures for type 'string' are considered only when no other index signatures apply. let stringIndexInfo: IndexInfo | undefined; let applicableInfo: IndexInfo | undefined; let applicableInfos: IndexInfo[] | undefined; @@ -12612,11 +12613,12 @@ namespace ts { if (declaration.parameters.length === 1) { const parameter = declaration.parameters[0]; if (parameter.type) { - const keyType = getTypeFromTypeNode(parameter.type); - if (isValidIndexKeyType(keyType) && !findIndexInfo(indexInfos, keyType)) { - indexInfos.push(createIndexInfo(keyType, declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration)); - } + forEachType(getTypeFromTypeNode(parameter.type), keyType => { + if (isValidIndexKeyType(keyType) && !findIndexInfo(indexInfos, keyType)) { + indexInfos.push(createIndexInfo(keyType, declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, + hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration)); + } + }); } } } @@ -14378,11 +14380,6 @@ namespace ts { /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, origin); } - function getNonEnumNumberIndexInfo(type: Type) { - const numberIndexInfo = getIndexInfoOfType(type, numberType); - return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined; - } - function getIndexType(type: Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): Type { type = getReducedType(type); return type.flags & TypeFlags.Union ? getIntersectionType(map((type as UnionType).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : @@ -21520,10 +21517,8 @@ namespace ts { // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol); - const stringIndexType = getIndexTypeOfType(source, stringType); - const numberIndexInfo = getNonEnumNumberIndexInfo(source); - const numberIndexType = numberIndexInfo && numberIndexInfo.type; - inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target)); + const indexTypes = map(getIndexInfosOfType(source), info => info !== enumNumberIndexInfo ? info.type : neverType); + inferFromTypes(getUnionType(concatenate(propTypes, indexTypes)), getTemplateTypeFromMappedType(target)); return true; } return false; @@ -23465,14 +23460,11 @@ namespace ts { } function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) { - if (getIndexInfoOfType(type, stringType)) { - return true; - } const prop = getPropertyOfType(type, propName); if (prop) { return prop.flags & SymbolFlags.Optional ? true : assumeTrue; } - return !assumeTrue; + return getApplicableIndexInfoForName(type, propName) ? true : !assumeTrue; } function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) { @@ -25331,6 +25323,7 @@ namespace ts { } function getIndexTypeOfContextualType(type: Type, keyType: Type) { + // We avoid calling getApplicableIndexInfo here because it performs potentially expensive intersection reduction. return mapType(type, t => findApplicableIndexInfo(getIndexInfosOfStructuredType(t), keyType)?.type, /*noReductions*/ true); } @@ -41145,14 +41138,11 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } const type = getTypeFromTypeNode(parameter.type); - if (!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol | TypeFlags.TemplateLiteral))) { - if (type.flags & TypeFlags.Union && allTypesAssignableToKind(type, TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol, /*strict*/ true)) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); - } - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type); + if (someType(type, t => !!(t.flags & (TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.Instantiable)) && !isPatternLiteralType(type))) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead); } - if (type.flags & TypeFlags.TemplateLiteral && !isPatternLiteralType(type)) { - return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_generic_type); + if (!everyType(type, t => !!(t.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol | TypeFlags.TemplateLiteral)))) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type); } if (!node.type) { return grammarErrorOnNode(node, Diagnostics.An_index_signature_must_have_a_type_annotation); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index fdb10eaf5b0ed..670f01cb54a50 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -891,10 +891,6 @@ "category": "Error", "code": 1268 }, - "An index signature parameter type cannot be a generic type.": { - "category": "Error", - "code": 1269 - }, "'with' statements are not allowed in an async function block.": { "category": "Error", @@ -1000,7 +996,7 @@ "category": "Error", "code": 1335 }, - "An index signature parameter type cannot be a union type. Consider using a mapped object type instead.": { + "An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.": { "category": "Error", "code": 1337 }, diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 4cf93b42e7f5a..4130d7fc84f9e 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -141,6 +141,7 @@ namespace ts { function visitObjectType(type: ObjectType): void { const resolved = resolveStructuredTypeMembers(type); for (const info of resolved.indexInfos) { + visitType(info.keyType); visitType(info.type); } for (const signature of resolved.callSignatures) { diff --git a/src/services/codefixes/convertToMappedObjectType.ts b/src/services/codefixes/convertToMappedObjectType.ts index ec49f144f5b2e..76da5233a513f 100644 --- a/src/services/codefixes/convertToMappedObjectType.ts +++ b/src/services/codefixes/convertToMappedObjectType.ts @@ -2,7 +2,7 @@ namespace ts.codefix { const fixIdAddMissingTypeof = "fixConvertToMappedObjectType"; const fixId = fixIdAddMissingTypeof; - const errorCodes = [Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead.code]; + const errorCodes = [Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead.code]; type FixableDeclaration = InterfaceDeclaration | TypeAliasDeclaration; From bed7008fa979a948a221943b18def07f2eed016d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Jun 2021 11:36:47 -0700 Subject: [PATCH 30/56] Accept new baselines --- ...cIndexTypeHasSensibleErrorMessage.errors.txt | 4 ++-- .../reference/indexerConstraints2.errors.txt | 17 +++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt b/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt index 850190d1552c0..376cf0741d664 100644 --- a/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt +++ b/tests/baselines/reference/genericIndexTypeHasSensibleErrorMessage.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/genericIndexTypeHasSensibleErrorMessage.ts(1,33): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. +tests/cases/compiler/genericIndexTypeHasSensibleErrorMessage.ts(1,33): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. ==== tests/cases/compiler/genericIndexTypeHasSensibleErrorMessage.ts (1 errors) ==== type Wat = { [x: T]: string }; ~ -!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. \ No newline at end of file +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 8863b842e7f43..6fd034e23bc71 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -2,15 +2,14 @@ tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: 'number' index t tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: 'number' index type 'A' is not assignable to 'string' index type 'B'. tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. -tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. +tests/cases/compiler/indexerConstraints2.ts(52,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. tests/cases/compiler/indexerConstraints2.ts(58,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. -tests/cases/compiler/indexerConstraints2.ts(64,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. -tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. -tests/cases/compiler/indexerConstraints2.ts(74,6): error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. +tests/cases/compiler/indexerConstraints2.ts(70,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. +tests/cases/compiler/indexerConstraints2.ts(74,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signature must have a type annotation. -==== tests/cases/compiler/indexerConstraints2.ts (10 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (9 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -72,7 +71,7 @@ tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signat interface O { [u: IndexableUnion]: A; ~ -!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. } type NonIndexableUnion = boolean | {}; @@ -87,8 +86,6 @@ tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signat interface Q { [u: NonIndexableUnion2]: A; - ~ -!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. } type NonIndexableUnion3 = "foo" | 42; @@ -96,13 +93,13 @@ tests/cases/compiler/indexerConstraints2.ts(79,5): error TS1021: An index signat interface R { [u: NonIndexableUnion3]: A; ~ -!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. } interface S { [u: "foo" | "bar"]: A; ~ -!!! error TS1337: An index signature parameter type cannot be a union type. Consider using a mapped object type instead. +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. } type Key = string; From a880248e90732666faeddc745e30673a76de02e5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Jun 2021 16:46:38 -0700 Subject: [PATCH 31/56] Check duplicate index signatures / remove redundant template literals from unions with string --- src/compiler/checker.ts | 44 +++++++++++++--------------- src/compiler/diagnosticMessages.json | 6 +--- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b5c240fa69c53..133a1ab68bd82 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13791,7 +13791,7 @@ namespace ts { const t = types[i]; const flags = t.flags; const remove = - flags & TypeFlags.StringLiteral && includes & TypeFlags.String || + flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && includes & TypeFlags.String || flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number || flags & TypeFlags.BigIntLiteral && includes & TypeFlags.BigInt || flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol || @@ -13861,7 +13861,7 @@ namespace ts { if (includes & TypeFlags.AnyOrUnknown) { return includes & TypeFlags.Any ? includes & TypeFlags.IncludesWildcard ? wildcardType : anyType : unknownType; } - if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { + if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { removeRedundantLiteralTypes(typeSet, includes, !!(unionReduction & UnionReduction.Subtype)); } if (includes & TypeFlags.StringLiteral && includes & TypeFlags.TemplateLiteral) { @@ -33276,31 +33276,27 @@ namespace ts { // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration const indexSymbol = getIndexSymbol(getSymbolOfNode(node)!); if (indexSymbol?.declarations) { - let seenNumericIndexer = false; - let seenStringIndexer = false; - for (const decl of indexSymbol.declarations) { - const declaration = decl as SignatureDeclaration; + const indexSignatureMap = new Map(); + for (const declaration of (indexSymbol.declarations as IndexSignatureDeclaration[])) { if (declaration.parameters.length === 1 && declaration.parameters[0].type) { - switch (declaration.parameters[0].type.kind) { - case SyntaxKind.StringKeyword: - if (!seenStringIndexer) { - seenStringIndexer = true; - } - else { - error(declaration, Diagnostics.Duplicate_string_index_signature); - } - break; - case SyntaxKind.NumberKeyword: - if (!seenNumericIndexer) { - seenNumericIndexer = true; - } - else { - error(declaration, Diagnostics.Duplicate_number_index_signature); - } - break; - } + forEachType(getTypeFromTypeNode(declaration.parameters[0].type), type => { + const entry = indexSignatureMap.get(getTypeId(type)); + if (entry) { + entry.declarations.push(declaration); + } + else { + indexSignatureMap.set(getTypeId(type), { type, declarations: [declaration] }); + } + }); } } + indexSignatureMap.forEach(entry => { + if (entry.declarations.length > 1) { + for (const declaration of entry.declarations) { + error(declaration, Diagnostics.Duplicate_index_signature_for_type_0, typeToString(entry.type)); + } + } + }); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 670f01cb54a50..8b627b8ffbc7e 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1698,14 +1698,10 @@ "category": "Error", "code": 2373 }, - "Duplicate string index signature.": { + "Duplicate index signature for type '{0}'.": { "category": "Error", "code": 2374 }, - "Duplicate number index signature.": { - "category": "Error", - "code": 2375 - }, "A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers.": { "category": "Error", "code": 2376 From dccec9abe9e1106c01ef624137c558bfd5bcf870 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Jun 2021 16:46:46 -0700 Subject: [PATCH 32/56] Accept new baselines --- .../duplicateNumericIndexers.errors.txt | 48 ++++++++++++------- .../duplicateStringIndexers.errors.txt | 44 ++++++++++++----- .../genericClassesRedeclaration.errors.txt | 9 ++-- .../interfaceMemberValidation.errors.txt | 9 ++-- .../multipleNumericIndexers.errors.txt | 45 +++++++++++------ .../multipleStringIndexers.errors.txt | 44 ++++++++++++----- .../optionalPropertiesSyntax.errors.txt | 17 ++++--- .../reference/templateLiteralTypes2.types | 2 +- .../typeOfEnumAndVarRedeclarations.errors.txt | 9 ++-- 9 files changed, 152 insertions(+), 75 deletions(-) diff --git a/tests/baselines/reference/duplicateNumericIndexers.errors.txt b/tests/baselines/reference/duplicateNumericIndexers.errors.txt index c4c7883021a3c..435a26293573c 100644 --- a/tests/baselines/reference/duplicateNumericIndexers.errors.txt +++ b/tests/baselines/reference/duplicateNumericIndexers.errors.txt @@ -1,60 +1,74 @@ -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(5,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(9,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(10,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(14,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(15,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(20,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(25,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/members/duplicateNumericIndexers.ts(30,5): error TS2375: Duplicate number index signature. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(4,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(5,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(9,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(10,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(14,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(15,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(19,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(20,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(24,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(25,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(29,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/duplicateNumericIndexers.ts(30,5): error TS2374: Duplicate index signature for type 'number'. +lib.es5.d.ts(514,5): error TS2374: Duplicate index signature for type 'number'. +lib.es5.d.ts(1401,5): error TS2374: Duplicate index signature for type 'number'. -==== tests/cases/conformance/types/members/duplicateNumericIndexers.ts (8 errors) ==== +==== tests/cases/conformance/types/members/duplicateNumericIndexers.ts (12 errors) ==== // it is an error to have duplicate index signatures of the same kind in a type interface Number { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } interface String { [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } interface Array { [x: number]: T; ~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: T; ~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } class C { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } interface I { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } var a: { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/duplicateStringIndexers.errors.txt b/tests/baselines/reference/duplicateStringIndexers.errors.txt index 9eebe6f78928d..84b8fb395b662 100644 --- a/tests/baselines/reference/duplicateStringIndexers.errors.txt +++ b/tests/baselines/reference/duplicateStringIndexers.errors.txt @@ -1,55 +1,73 @@ -tests/cases/conformance/types/members/duplicateStringIndexers.ts(6,9): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/members/duplicateStringIndexers.ts(11,9): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/members/duplicateStringIndexers.ts(16,9): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/members/duplicateStringIndexers.ts(21,9): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/members/duplicateStringIndexers.ts(26,9): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/members/duplicateStringIndexers.ts(31,9): error TS2374: Duplicate string index signature. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(5,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(6,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(10,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(11,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(15,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(16,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(20,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(21,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(25,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(26,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(30,9): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/members/duplicateStringIndexers.ts(31,9): error TS2374: Duplicate index signature for type 'string'. -==== tests/cases/conformance/types/members/duplicateStringIndexers.ts (6 errors) ==== +==== tests/cases/conformance/types/members/duplicateStringIndexers.ts (12 errors) ==== // it is an error to have duplicate index signatures of the same kind in a type module test { interface Number { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } interface String { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } interface Array { [x: string]: T; + ~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: T; ~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } class C { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } interface I { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } var a: { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } } \ No newline at end of file diff --git a/tests/baselines/reference/genericClassesRedeclaration.errors.txt b/tests/baselines/reference/genericClassesRedeclaration.errors.txt index 197701c862470..1908b46ab6126 100644 --- a/tests/baselines/reference/genericClassesRedeclaration.errors.txt +++ b/tests/baselines/reference/genericClassesRedeclaration.errors.txt @@ -1,14 +1,17 @@ +tests/cases/compiler/genericClassesRedeclaration.ts(3,9): error TS2374: Duplicate index signature for type 'string'. tests/cases/compiler/genericClassesRedeclaration.ts(16,11): error TS2300: Duplicate identifier 'StringHashTable'. tests/cases/compiler/genericClassesRedeclaration.ts(29,11): error TS2300: Duplicate identifier 'IdentifierNameHashTable'. -tests/cases/compiler/genericClassesRedeclaration.ts(42,9): error TS2374: Duplicate string index signature. +tests/cases/compiler/genericClassesRedeclaration.ts(42,9): error TS2374: Duplicate index signature for type 'string'. tests/cases/compiler/genericClassesRedeclaration.ts(55,11): error TS2300: Duplicate identifier 'StringHashTable'. tests/cases/compiler/genericClassesRedeclaration.ts(68,11): error TS2300: Duplicate identifier 'IdentifierNameHashTable'. -==== tests/cases/compiler/genericClassesRedeclaration.ts (5 errors) ==== +==== tests/cases/compiler/genericClassesRedeclaration.ts (6 errors) ==== declare module TypeScript { interface IIndexable { [s: string]: T; + ~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. } function createIntrinsicsObject(): IIndexable; interface IHashTable { @@ -53,7 +56,7 @@ tests/cases/compiler/genericClassesRedeclaration.ts(68,11): error TS2300: Duplic interface IIndexable { [s: string]: T; ~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } function createIntrinsicsObject(): IIndexable; interface IHashTable { diff --git a/tests/baselines/reference/interfaceMemberValidation.errors.txt b/tests/baselines/reference/interfaceMemberValidation.errors.txt index 53274b7592fce..ab973e7413cd6 100644 --- a/tests/baselines/reference/interfaceMemberValidation.errors.txt +++ b/tests/baselines/reference/interfaceMemberValidation.errors.txt @@ -2,10 +2,11 @@ tests/cases/compiler/interfaceMemberValidation.ts(2,11): error TS2430: Interface Types of property 'name' are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/compiler/interfaceMemberValidation.ts(5,2): error TS2411: Property 'bar' of type '{ (): any; (): any; }' is not assignable to 'string' index type 'number'. -tests/cases/compiler/interfaceMemberValidation.ts(10,2): error TS2374: Duplicate string index signature. +tests/cases/compiler/interfaceMemberValidation.ts(9,2): error TS2374: Duplicate index signature for type 'string'. +tests/cases/compiler/interfaceMemberValidation.ts(10,2): error TS2374: Duplicate index signature for type 'string'. -==== tests/cases/compiler/interfaceMemberValidation.ts (3 errors) ==== +==== tests/cases/compiler/interfaceMemberValidation.ts (4 errors) ==== interface i1 { name: string; } interface i2 extends i1 { name: number; yo: string; } ~~ @@ -21,7 +22,9 @@ tests/cases/compiler/interfaceMemberValidation.ts(10,2): error TS2374: Duplicate new():void; new():void; [s:string]:number; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [s:string]:number; ~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/multipleNumericIndexers.errors.txt b/tests/baselines/reference/multipleNumericIndexers.errors.txt index e3eaa94fa5281..998327b101dfd 100644 --- a/tests/baselines/reference/multipleNumericIndexers.errors.txt +++ b/tests/baselines/reference/multipleNumericIndexers.errors.txt @@ -1,52 +1,67 @@ -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(5,5): error TS2375: Duplicate number index signature. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(4,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(5,5): error TS2374: Duplicate index signature for type 'number'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(8,11): error TS2428: All declarations of 'I' must have identical type parameters. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(10,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(15,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(20,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(25,5): error TS2375: Duplicate number index signature. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(9,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(10,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(14,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(15,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(19,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(20,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(24,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(25,5): error TS2374: Duplicate index signature for type 'number'. tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(28,11): error TS2428: All declarations of 'I' must have identical type parameters. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(29,5): error TS2375: Duplicate number index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(30,5): error TS2375: Duplicate number index signature. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(29,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts(30,5): error TS2374: Duplicate index signature for type 'number'. -==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts (9 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericIndexers.ts (14 errors) ==== // Multiple indexers of the same type are an error class C { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } interface I { ~ !!! error TS2428: All declarations of 'I' must have identical type parameters. [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } var a: { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } var b: { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string ~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } = { 1: '', "2": '' } class C2 { [x: number]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } interface I { @@ -54,9 +69,9 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleNumericI !!! error TS2428: All declarations of 'I' must have identical type parameters. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. [x: number]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/multipleStringIndexers.errors.txt b/tests/baselines/reference/multipleStringIndexers.errors.txt index 6aa4172476b43..a17c3687bf5d7 100644 --- a/tests/baselines/reference/multipleStringIndexers.errors.txt +++ b/tests/baselines/reference/multipleStringIndexers.errors.txt @@ -1,52 +1,70 @@ -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(5,5): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(10,5): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(15,5): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(20,5): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(25,5): error TS2374: Duplicate string index signature. -tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(30,5): error TS2374: Duplicate string index signature. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(4,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(5,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(9,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(10,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(14,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(15,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(19,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(20,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(24,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(25,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(29,5): error TS2374: Duplicate index signature for type 'string'. +tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts(30,5): error TS2374: Duplicate index signature for type 'string'. -==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts (6 errors) ==== +==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/multipleStringIndexers.ts (12 errors) ==== // Multiple indexers of the same type are an error class C { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } interface I { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } var a: { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } var b: { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } = { y: '' } class C2 { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } interface I2 { [x: string]: string; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'string'. [x: string]: string; ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2374: Duplicate string index signature. +!!! error TS2374: Duplicate index signature for type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/optionalPropertiesSyntax.errors.txt b/tests/baselines/reference/optionalPropertiesSyntax.errors.txt index e7cc874212710..1c24acf39cc93 100644 --- a/tests/baselines/reference/optionalPropertiesSyntax.errors.txt +++ b/tests/baselines/reference/optionalPropertiesSyntax.errors.txt @@ -8,15 +8,16 @@ tests/cases/compiler/optionalPropertiesSyntax.ts(24,5): error TS2300: Duplicate tests/cases/compiler/optionalPropertiesSyntax.ts(24,5): error TS2687: All declarations of 'prop' must have identical modifiers. tests/cases/compiler/optionalPropertiesSyntax.ts(25,5): error TS2300: Duplicate identifier 'prop'. tests/cases/compiler/optionalPropertiesSyntax.ts(25,5): error TS2687: All declarations of 'prop' must have identical modifiers. -tests/cases/compiler/optionalPropertiesSyntax.ts(32,5): error TS2375: Duplicate number index signature. +tests/cases/compiler/optionalPropertiesSyntax.ts(31,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/compiler/optionalPropertiesSyntax.ts(32,5): error TS2374: Duplicate index signature for type 'number'. tests/cases/compiler/optionalPropertiesSyntax.ts(32,18): error TS1005: ';' expected. tests/cases/compiler/optionalPropertiesSyntax.ts(32,19): error TS1131: Property or signature expected. tests/cases/compiler/optionalPropertiesSyntax.ts(33,5): error TS1131: Property or signature expected. -tests/cases/compiler/optionalPropertiesSyntax.ts(33,7): error TS2375: Duplicate number index signature. -tests/cases/compiler/optionalPropertiesSyntax.ts(34,5): error TS2375: Duplicate number index signature. +tests/cases/compiler/optionalPropertiesSyntax.ts(33,7): error TS2374: Duplicate index signature for type 'number'. +tests/cases/compiler/optionalPropertiesSyntax.ts(34,5): error TS2374: Duplicate index signature for type 'number'. -==== tests/cases/compiler/optionalPropertiesSyntax.ts (16 errors) ==== +==== tests/cases/compiler/optionalPropertiesSyntax.ts (17 errors) ==== interface fnSigs { //functions signatures can be optional fn(): void; @@ -68,9 +69,11 @@ tests/cases/compiler/optionalPropertiesSyntax.ts(34,5): error TS2375: Duplicate interface indexSig { //Index signatures can't be optional [idx: number]: any; + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. [idx: number]?: any; //err ~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. ~ !!! error TS1005: ';' expected. ~ @@ -79,8 +82,8 @@ tests/cases/compiler/optionalPropertiesSyntax.ts(34,5): error TS2375: Duplicate ~ !!! error TS1131: Property or signature expected. ~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. [idx?: number]: any; //err ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. +!!! error TS2374: Duplicate index signature for type 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/templateLiteralTypes2.types b/tests/baselines/reference/templateLiteralTypes2.types index 24096c9d782ec..e771c63c5357c 100644 --- a/tests/baselines/reference/templateLiteralTypes2.types +++ b/tests/baselines/reference/templateLiteralTypes2.types @@ -255,7 +255,7 @@ function ft13(s: string, cond: boolean) { } type T0 = string | `${number}px`; ->T0 : T0 +>T0 : string function ft14(t: `foo${number}`) { >ft14 : (t: `foo${number}`) => void diff --git a/tests/baselines/reference/typeOfEnumAndVarRedeclarations.errors.txt b/tests/baselines/reference/typeOfEnumAndVarRedeclarations.errors.txt index 4303512121264..7975a960bfeef 100644 --- a/tests/baselines/reference/typeOfEnumAndVarRedeclarations.errors.txt +++ b/tests/baselines/reference/typeOfEnumAndVarRedeclarations.errors.txt @@ -1,9 +1,10 @@ tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts(8,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'typeof E', but here has type '{ readonly [x: number]: string; readonly a: E; readonly b: E; }'. tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts(10,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'typeof E', but here has type '{ readonly [x: number]: string; readonly a: E; readonly b: E; }'. -tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts(10,70): error TS2375: Duplicate number index signature. +tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts(10,40): error TS2374: Duplicate index signature for type 'number'. +tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts(10,70): error TS2374: Duplicate index signature for type 'number'. -==== tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts (3 errors) ==== +==== tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts (4 errors) ==== enum E { a } @@ -20,5 +21,7 @@ tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts(10,70): error TS2375: Dup ~ !!! error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'typeof E', but here has type '{ readonly [x: number]: string; readonly a: E; readonly b: E; }'. !!! related TS6203 tests/cases/compiler/typeOfEnumAndVarRedeclarations.ts:9:5: 'y' was also declared here. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2375: Duplicate number index signature. \ No newline at end of file +!!! error TS2374: Duplicate index signature for type 'number'. \ No newline at end of file From 535c5e32aee5f511f038fdcd1adc4e8c9511053b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 8 Jun 2021 08:12:37 -0700 Subject: [PATCH 33/56] Include key type in diagnostic / check symbol-named properties --- src/compiler/checker.ts | 26 +++++++++++++------------- src/compiler/diagnosticMessages.json | 6 +++++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 133a1ab68bd82..711ab3e62cf00 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19393,14 +19393,9 @@ namespace ts { if (isIgnoredJsxProperty(source, prop)) { continue; } - const nameType = getSymbolLinks(prop).nameType; - if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) { - continue; - } - if (keyType === stringType || keyType === numberType && isNumericLiteralName(prop.escapedName) || - isTypeAssignableTo(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), keyType)) { + if (isApplicableIndexType(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), keyType)) { const propType = getTypeOfSymbol(prop); - const type = propType.flags & TypeFlags.Undefined || !(keyType === stringType && prop.flags & SymbolFlags.Optional) + const type = propType.flags & TypeFlags.Undefined || keyType === numberType || !(prop.flags & SymbolFlags.Optional) ? propType : getTypeWithFacts(propType, TypeFacts.NEUndefined); const related = isRelatedTo(type, targetInfo.type, reportErrors); @@ -19414,8 +19409,8 @@ namespace ts { } } for (const info of getIndexInfosOfType(source)) { - if (isTypeAssignableTo(info.keyType, keyType)) { - const related = indexTypeRelatedTo(info.type, targetInfo.type, reportErrors); + if (isApplicableIndexType(info.keyType, keyType)) { + const related = indexInfoRelatedTo(info, targetInfo, reportErrors); if (!related) { return Ternary.False; } @@ -19425,10 +19420,15 @@ namespace ts { return result; } - function indexTypeRelatedTo(sourceType: Type, targetType: Type, reportErrors: boolean) { - const related = isRelatedTo(sourceType, targetType, reportErrors); + function indexInfoRelatedTo(sourceInfo: IndexInfo, targetInfo: IndexInfo, reportErrors: boolean) { + const related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors); if (!related && reportErrors) { - reportError(Diagnostics.Index_signatures_are_incompatible); + if (sourceInfo.keyType === targetInfo.keyType) { + reportError(Diagnostics._0_index_signatures_are_incompatible, typeToString(sourceInfo.keyType)); + } + else { + reportError(Diagnostics._0_and_1_index_signatures_are_incompatible, typeToString(sourceInfo.keyType), typeToString(targetInfo.keyType)); + } } return related; } @@ -19455,7 +19455,7 @@ namespace ts { function typeRelatedToIndexInfo(source: Type, targetInfo: IndexInfo, reportErrors: boolean, intersectionState: IntersectionState): Ternary { const sourceInfo = getApplicableIndexInfo(source, targetInfo.keyType); if (sourceInfo) { - return indexTypeRelatedTo(sourceInfo.type, targetInfo.type, reportErrors); + return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } if (!(intersectionState & IntersectionState.Source) && isObjectTypeWithInferableIndex(source)) { // Intersection constituents are never considered to have an inferred index signature diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 8b627b8ffbc7e..447ad821968d2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1522,7 +1522,7 @@ "category": "Error", "code": 2329 }, - "Index signatures are incompatible.": { + "'{0}' and '{1}' index signatures are incompatible.": { "category": "Error", "code": 2330 }, @@ -2674,6 +2674,10 @@ "category": "Error", "code": 2633 }, + "'{0}' index signatures are incompatible.": { + "category": "Error", + "code": 2634 + }, "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { "category": "Error", From cf8b5476209538f50b74d2b897f3d8b7f3835e49 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 8 Jun 2021 08:13:00 -0700 Subject: [PATCH 34/56] Accept new baselines --- ...ignmentCompatWithNumericIndexer.errors.txt | 24 +++++++------- ...gnmentCompatWithNumericIndexer2.errors.txt | 24 +++++++------- ...gnmentCompatWithNumericIndexer3.errors.txt | 12 +++---- ...signmentCompatWithStringIndexer.errors.txt | 32 +++++++++---------- ...ignmentCompatWithStringIndexer2.errors.txt | 32 +++++++++---------- ...ignmentCompatWithStringIndexer3.errors.txt | 8 ++--- ...opertyNamesContextualType10_ES5.errors.txt | 4 +-- ...opertyNamesContextualType10_ES6.errors.txt | 4 +-- ...ropertyNamesContextualType8_ES5.errors.txt | 4 +-- ...ropertyNamesContextualType8_ES6.errors.txt | 4 +-- ...ropertyNamesContextualType9_ES5.errors.txt | 4 +-- ...ropertyNamesContextualType9_ES6.errors.txt | 4 +-- ...rivedTypeIncompatibleSignatures.errors.txt | 8 ++--- ...IndexSignatureContainingObject1.errors.txt | 4 +-- ...IndexSignatureContainingObject2.errors.txt | 4 +-- ...gIndexersFromDifferentBaseTypes.errors.txt | 8 ++--- ...intersectionWithIndexSignatures.errors.txt | 4 +-- .../subtypingWithNumericIndexer.errors.txt | 8 ++--- .../subtypingWithNumericIndexer2.errors.txt | 16 +++++----- .../subtypingWithNumericIndexer3.errors.txt | 16 +++++----- .../subtypingWithNumericIndexer4.errors.txt | 12 +++---- .../subtypingWithNumericIndexer5.errors.txt | 16 +++++----- .../subtypingWithStringIndexer.errors.txt | 8 ++--- .../subtypingWithStringIndexer2.errors.txt | 16 +++++----- .../subtypingWithStringIndexer3.errors.txt | 16 +++++----- .../subtypingWithStringIndexer4.errors.txt | 12 +++---- 26 files changed, 152 insertions(+), 152 deletions(-) diff --git a/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt b/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt index 7358455430c80..2a2a3f3abcef5 100644 --- a/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithNumericIndexer.errors.txt @@ -1,23 +1,23 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(14,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(18,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Base' is missing the following properties from type 'Derived2': baz, bar tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(32,9): error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(33,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(36,9): error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts(37,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. Type 'Base' is not assignable to type 'Derived2'. @@ -39,7 +39,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer.ts:4:34: 'bar' is declared here. @@ -48,7 +48,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar module Generics { @@ -66,13 +66,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b; // error ~ !!! error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Derived' is not assignable to type 'T'. !!! error TS2322: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived'. @@ -80,13 +80,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b2; // error ~ !!! error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Derived2' is not assignable to type 'T'. !!! error TS2322: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. diff --git a/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt b/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt index f4b2e46f44f96..e294347084798 100644 --- a/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithNumericIndexer2.errors.txt @@ -1,23 +1,23 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(14,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(18,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Base' is missing the following properties from type 'Derived2': baz, bar tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(32,9): error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(33,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(36,9): error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts(37,9): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. Type 'Base' is not assignable to type 'Derived2'. @@ -39,7 +39,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer2.ts:4:34: 'bar' is declared here. @@ -48,7 +48,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar module Generics { @@ -66,13 +66,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b; // error ~ !!! error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Derived' is not assignable to type 'T'. !!! error TS2322: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived'. @@ -80,13 +80,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b2; // error ~ !!! error TS2322: Type '{ [x: number]: Derived2; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Derived2' is not assignable to type 'T'. !!! error TS2322: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. diff --git a/tests/baselines/reference/assignmentCompatWithNumericIndexer3.errors.txt b/tests/baselines/reference/assignmentCompatWithNumericIndexer3.errors.txt index 1f279ba2858f7..5b72d9f1ec2de 100644 --- a/tests/baselines/reference/assignmentCompatWithNumericIndexer3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithNumericIndexer3.errors.txt @@ -1,11 +1,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer3.ts(14,1): error TS2322: Type '{ [x: number]: Base; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer3.ts(23,1): error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Property 'baz' is missing in type 'Derived' but required in type 'Derived2'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer3.ts(33,9): error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. @@ -27,7 +27,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b; // error ~ !!! error TS2322: Type '{ [x: number]: Base; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer3.ts:4:34: 'bar' is declared here. b = a; // ok @@ -41,7 +41,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: number]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Property 'baz' is missing in type 'Derived' but required in type 'Derived2'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithNumericIndexer3.ts:5:38: 'baz' is declared here. @@ -56,7 +56,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b; // error ~ !!! error TS2322: Type '{ [x: number]: Derived; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'Derived' is not assignable to type 'T'. !!! error TS2322: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. b = a; // ok diff --git a/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt b/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt index b3970325dc298..9c5b1e1c11fbc 100644 --- a/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithStringIndexer.errors.txt @@ -1,29 +1,29 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(15,1): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(19,1): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is missing the following properties from type 'Derived2': baz, bar tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(33,5): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(41,5): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is not assignable to type 'Derived2'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(46,9): error TS2322: Type '{ [x: string]: Derived; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(47,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(50,9): error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts(51,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. Type 'Base' is not assignable to type 'Derived2'. @@ -46,7 +46,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer.ts:4:34: 'bar' is declared here. @@ -55,7 +55,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar module Generics { @@ -73,7 +73,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b1 = a1; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Base' is not assignable to type 'Derived'. class B2 extends A { @@ -85,7 +85,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a1; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. function foo() { @@ -94,13 +94,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a3 = b3; // error ~~ !!! error TS2322: Type '{ [x: string]: Derived; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Derived' is not assignable to type 'T'. !!! error TS2322: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b3 = a3; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived'. @@ -108,13 +108,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a3 = b4; // error ~~ !!! error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Derived2' is not assignable to type 'T'. !!! error TS2322: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b4 = a3; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. } diff --git a/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt b/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt index f90f8a41feb05..6247b5f1c48bc 100644 --- a/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithStringIndexer2.errors.txt @@ -1,29 +1,29 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(15,1): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(19,1): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is missing the following properties from type 'Derived2': baz, bar tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(33,5): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(41,5): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is not assignable to type 'Derived2'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(46,9): error TS2322: Type '{ [x: string]: Derived; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(47,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'T' is not assignable to type 'Derived'. Type 'Base' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(50,9): error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts(51,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'T' is not assignable to type 'Derived2'. Type 'Base' is not assignable to type 'Derived2'. @@ -46,7 +46,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer2.ts:4:34: 'bar' is declared here. @@ -55,7 +55,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Base' is missing the following properties from type 'Derived2': baz, bar module Generics { @@ -73,7 +73,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b1 = a1; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Base' is not assignable to type 'Derived'. interface B2 extends A { @@ -85,7 +85,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme b2 = a1; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. function foo() { @@ -94,13 +94,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a3 = b3; // error ~~ !!! error TS2322: Type '{ [x: string]: Derived; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Derived' is not assignable to type 'T'. !!! error TS2322: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b3 = a3; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived'. @@ -108,13 +108,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a3 = b4; // error ~~ !!! error TS2322: Type '{ [x: string]: Derived2; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'Derived2' is not assignable to type 'T'. !!! error TS2322: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. b4 = a3; // error ~~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: Derived2; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'Derived2'. !!! error TS2322: Type 'Base' is not assignable to type 'Derived2'. } diff --git a/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt b/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt index dc1acb8de071a..d3735e6f19901 100644 --- a/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithStringIndexer3.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts(7,8): error TS2304: Cannot find name 'A'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts(20,9): error TS2322: Type '{ [x: string]: string; }' is not assignable to type 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithStringIndexer3.ts(21,9): error TS2322: Type 'A' is not assignable to type '{ [x: string]: string; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'T' is not assignable to type 'string'. Type 'Derived' is not assignable to type 'string'. @@ -34,13 +34,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme a = b; // error ~ !!! error TS2322: Type '{ [x: string]: string; }' is not assignable to type 'A'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'string' is not assignable to type 'T'. !!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'. b = a; // error ~ !!! error TS2322: Type 'A' is not assignable to type '{ [x: string]: string; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'T' is not assignable to type 'string'. !!! error TS2322: Type 'Derived' is not assignable to type 'string'. } diff --git a/tests/baselines/reference/computedPropertyNamesContextualType10_ES5.errors.txt b/tests/baselines/reference/computedPropertyNamesContextualType10_ES5.errors.txt index 7fa95fe942616..dbcdb5acada0a 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType10_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesContextualType10_ES5.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType10_ES5.ts(5,5): error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'string | number' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'. @@ -12,7 +12,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualTy var o: I = { ~ !!! error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'string | number' is not assignable to type 'boolean'. !!! error TS2322: Type 'string' is not assignable to type 'boolean'. [+"foo"]: "", diff --git a/tests/baselines/reference/computedPropertyNamesContextualType10_ES6.errors.txt b/tests/baselines/reference/computedPropertyNamesContextualType10_ES6.errors.txt index 116cd1a25311e..bb84b1a83e866 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType10_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesContextualType10_ES6.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType10_ES6.ts(5,5): error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'string | number' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'. @@ -12,7 +12,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualTy var o: I = { ~ !!! error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' index signatures are incompatible. !!! error TS2322: Type 'string | number' is not assignable to type 'boolean'. !!! error TS2322: Type 'string' is not assignable to type 'boolean'. [+"foo"]: "", diff --git a/tests/baselines/reference/computedPropertyNamesContextualType8_ES5.errors.txt b/tests/baselines/reference/computedPropertyNamesContextualType8_ES5.errors.txt index ee36609095a04..eedc4e10ce9b0 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType8_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesContextualType8_ES5.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType8_ES5.ts(6,5): error TS2322: Type '{ [x: string]: string | number; }' is not assignable to type 'I'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string | number' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'. @@ -13,7 +13,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualTy var o: I = { ~ !!! error TS2322: Type '{ [x: string]: string | number; }' is not assignable to type 'I'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'string | number' is not assignable to type 'boolean'. !!! error TS2322: Type 'string' is not assignable to type 'boolean'. [""+"foo"]: "", diff --git a/tests/baselines/reference/computedPropertyNamesContextualType8_ES6.errors.txt b/tests/baselines/reference/computedPropertyNamesContextualType8_ES6.errors.txt index 1048fd2e119e7..4e5fa2a432db3 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType8_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesContextualType8_ES6.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType8_ES6.ts(6,5): error TS2322: Type '{ [x: string]: string | number; }' is not assignable to type 'I'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string | number' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'. @@ -13,7 +13,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualTy var o: I = { ~ !!! error TS2322: Type '{ [x: string]: string | number; }' is not assignable to type 'I'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'string | number' is not assignable to type 'boolean'. !!! error TS2322: Type 'string' is not assignable to type 'boolean'. [""+"foo"]: "", diff --git a/tests/baselines/reference/computedPropertyNamesContextualType9_ES5.errors.txt b/tests/baselines/reference/computedPropertyNamesContextualType9_ES5.errors.txt index e76b3a704dc6e..a9530da171c7e 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType9_ES5.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesContextualType9_ES5.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType9_ES5.ts(6,5): error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. - Index signatures are incompatible. + 'number' and 'string' index signatures are incompatible. Type 'string | number' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'. @@ -13,7 +13,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualTy var o: I = { ~ !!! error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' and 'string' index signatures are incompatible. !!! error TS2322: Type 'string | number' is not assignable to type 'boolean'. !!! error TS2322: Type 'string' is not assignable to type 'boolean'. [+"foo"]: "", diff --git a/tests/baselines/reference/computedPropertyNamesContextualType9_ES6.errors.txt b/tests/baselines/reference/computedPropertyNamesContextualType9_ES6.errors.txt index 468ad400c26cc..4a5758e5c1796 100644 --- a/tests/baselines/reference/computedPropertyNamesContextualType9_ES6.errors.txt +++ b/tests/baselines/reference/computedPropertyNamesContextualType9_ES6.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType9_ES6.ts(6,5): error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. - Index signatures are incompatible. + 'number' and 'string' index signatures are incompatible. Type 'string | number' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'. @@ -13,7 +13,7 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualTy var o: I = { ~ !!! error TS2322: Type '{ [x: number]: string | number; }' is not assignable to type 'I'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'number' and 'string' index signatures are incompatible. !!! error TS2322: Type 'string | number' is not assignable to type 'boolean'. !!! error TS2322: Type 'string' is not assignable to type 'boolean'. [+"foo"]: "", diff --git a/tests/baselines/reference/derivedTypeIncompatibleSignatures.errors.txt b/tests/baselines/reference/derivedTypeIncompatibleSignatures.errors.txt index 71fe36660c496..f02bfa2bc14fd 100644 --- a/tests/baselines/reference/derivedTypeIncompatibleSignatures.errors.txt +++ b/tests/baselines/reference/derivedTypeIncompatibleSignatures.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/derivedTypeIncompatibleSignatures.ts(21,11): error TS2430: Interface 'F' incorrectly extends interface 'E'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/compiler/derivedTypeIncompatibleSignatures.ts(29,11): error TS2430: Interface 'H' incorrectly extends interface 'G'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'number' is not assignable to type 'string'. @@ -30,7 +30,7 @@ tests/cases/compiler/derivedTypeIncompatibleSignatures.ts(29,11): error TS2430: interface F extends E { ~ !!! error TS2430: Interface 'F' incorrectly extends interface 'E'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'string' index signatures are incompatible. !!! error TS2430: Type 'number' is not assignable to type 'string'. [a: string]: number; // Number is not a subtype of string. Should error. } @@ -42,7 +42,7 @@ tests/cases/compiler/derivedTypeIncompatibleSignatures.ts(29,11): error TS2430: interface H extends G { ~ !!! error TS2430: Interface 'H' incorrectly extends interface 'G'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'number' index signatures are incompatible. !!! error TS2430: Type 'number' is not assignable to type 'string'. [a: number]: number; // Should error for the same reason } \ No newline at end of file diff --git a/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.errors.txt b/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.errors.txt index 56135cf8b0d14..cbb0fba87f162 100644 --- a/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.errors.txt +++ b/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.ts(41,3): error TS2322: Type 'Dictionary' is not assignable to type 'Record'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string' is not assignable to type 'Bar'. @@ -47,7 +47,7 @@ tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject1.ts(4 return result; ~~~~~~~~~~~~~~ !!! error TS2322: Type 'Dictionary' is not assignable to type 'Record'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'string' is not assignable to type 'Bar'. } \ No newline at end of file diff --git a/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.errors.txt b/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.errors.txt index 58de463148308..cef5fb902c6a4 100644 --- a/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.errors.txt +++ b/tests/baselines/reference/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.ts(42,3): error TS2322: Type 'Dictionary' is not assignable to type 'Record'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string' is not assignable to type 'Bar'. @@ -48,7 +48,7 @@ tests/cases/compiler/emptyObjectNotSubtypeOfIndexSignatureContainingObject2.ts(4 return result; ~~~~~~~~~~~~~~ !!! error TS2322: Type 'Dictionary' is not assignable to type 'Record'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Type 'string' is not assignable to type 'Bar'. } \ No newline at end of file diff --git a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.errors.txt b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.errors.txt index b99efb5e157ce..26cd375f6ebef 100644 --- a/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.errors.txt +++ b/tests/baselines/reference/inheritedStringIndexersFromDifferentBaseTypes.errors.txt @@ -1,8 +1,8 @@ tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes.ts(13,11): error TS2430: Interface 'E' incorrectly extends interface 'D'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'number' is not assignable to type 'string'. tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes.ts(28,11): error TS2430: Interface 'E2' incorrectly extends interface 'D2'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'number' is not assignable to type 'string'. @@ -22,7 +22,7 @@ tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes.ts(28,11): er interface E extends A, D { } // error ~ !!! error TS2430: Interface 'E' incorrectly extends interface 'D'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'string' index signatures are incompatible. !!! error TS2430: Type 'number' is not assignable to type 'string'. @@ -41,5 +41,5 @@ tests/cases/compiler/inheritedStringIndexersFromDifferentBaseTypes.ts(28,11): er interface E2 extends A2, D2 { } // error ~~ !!! error TS2430: Interface 'E2' incorrectly extends interface 'D2'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'number' index signatures are incompatible. !!! error TS2430: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/intersectionWithIndexSignatures.errors.txt b/tests/baselines/reference/intersectionWithIndexSignatures.errors.txt index 0837890bbe365..9d0699d2487bb 100644 --- a/tests/baselines/reference/intersectionWithIndexSignatures.errors.txt +++ b/tests/baselines/reference/intersectionWithIndexSignatures.errors.txt @@ -3,7 +3,7 @@ tests/cases/conformance/types/intersection/intersectionWithIndexSignatures.ts(17 Property 'a' is missing in type 'B' but required in type 'A'. tests/cases/conformance/types/intersection/intersectionWithIndexSignatures.ts(27,10): error TS2339: Property 'b' does not exist on type '{ a: string; }'. tests/cases/conformance/types/intersection/intersectionWithIndexSignatures.ts(29,7): error TS2322: Type 's' is not assignable to type '{ [key: string]: { a: string; b: string; }; }'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Property 'b' is missing in type '{ a: string; }' but required in type '{ a: string; b: string; }'. tests/cases/conformance/types/intersection/intersectionWithIndexSignatures.ts(35,1): error TS2322: Type '{ a: string; } & { b: number; }' is not assignable to type '{ [key: string]: string; }'. Property 'b' is incompatible with index signature. @@ -49,7 +49,7 @@ tests/cases/conformance/types/intersection/intersectionWithIndexSignatures.ts(35 const d: { [key: string]: {a: string, b: string} } = q; // Error ~ !!! error TS2322: Type 's' is not assignable to type '{ [key: string]: { a: string; b: string; }; }'. -!!! error TS2322: Index signatures are incompatible. +!!! error TS2322: 'string' index signatures are incompatible. !!! error TS2322: Property 'b' is missing in type '{ a: string; }' but required in type '{ a: string; b: string; }'. !!! related TS2728 tests/cases/conformance/types/intersection/intersectionWithIndexSignatures.ts:29:39: 'b' is declared here. diff --git a/tests/baselines/reference/subtypingWithNumericIndexer.errors.txt b/tests/baselines/reference/subtypingWithNumericIndexer.errors.txt index 0c79c352a4c85..5bc973332a950 100644 --- a/tests/baselines/reference/subtypingWithNumericIndexer.errors.txt +++ b/tests/baselines/reference/subtypingWithNumericIndexer.errors.txt @@ -1,9 +1,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer.ts(32,11): error TS2415: Class 'B3' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer.ts(36,11): error TS2415: Class 'B4' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. @@ -43,7 +43,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 extends A { ~~ !!! error TS2415: Class 'B3' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'Derived' is not assignable to type 'T'. !!! error TS2415: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. [x: number]: Derived; // error, BUG? @@ -52,7 +52,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B4 extends A { ~~ !!! error TS2415: Class 'B4' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'Derived2' is not assignable to type 'T'. !!! error TS2415: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. [x: number]: Derived2; // error, BUG? diff --git a/tests/baselines/reference/subtypingWithNumericIndexer2.errors.txt b/tests/baselines/reference/subtypingWithNumericIndexer2.errors.txt index ed48870168e18..619e25ce094e3 100644 --- a/tests/baselines/reference/subtypingWithNumericIndexer2.errors.txt +++ b/tests/baselines/reference/subtypingWithNumericIndexer2.errors.txt @@ -1,17 +1,17 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer2.ts(11,11): error TS2430: Interface 'B' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer2.ts(24,27): error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer2.ts(32,15): error TS2430: Interface 'B3' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Base' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer2.ts(36,15): error TS2430: Interface 'B4' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer2.ts(40,15): error TS2430: Interface 'B5' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. @@ -30,7 +30,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B extends A { ~ !!! error TS2430: Interface 'B' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'number' index signatures are incompatible. !!! error TS2430: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer2.ts:4:34: 'bar' is declared here. [x: number]: Base; // error @@ -58,7 +58,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B3 extends A { ~~ !!! error TS2430: Interface 'B3' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'number' index signatures are incompatible. !!! error TS2430: Type 'Base' is not assignable to type 'T'. !!! error TS2430: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. [x: number]: Base; // error @@ -67,7 +67,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B4 extends A { ~~ !!! error TS2430: Interface 'B4' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'number' index signatures are incompatible. !!! error TS2430: Type 'Derived' is not assignable to type 'T'. !!! error TS2430: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. [x: number]: Derived; // error @@ -76,7 +76,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B5 extends A { ~~ !!! error TS2430: Interface 'B5' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'number' index signatures are incompatible. !!! error TS2430: Type 'Derived2' is not assignable to type 'T'. !!! error TS2430: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. [x: number]: Derived2; // error diff --git a/tests/baselines/reference/subtypingWithNumericIndexer3.errors.txt b/tests/baselines/reference/subtypingWithNumericIndexer3.errors.txt index 08020cd5652d5..d3c67979ba5e1 100644 --- a/tests/baselines/reference/subtypingWithNumericIndexer3.errors.txt +++ b/tests/baselines/reference/subtypingWithNumericIndexer3.errors.txt @@ -1,17 +1,17 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer3.ts(11,7): error TS2415: Class 'B' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer3.ts(24,23): error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer3.ts(32,11): error TS2415: Class 'B3' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Base' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer3.ts(36,11): error TS2415: Class 'B4' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer3.ts(40,11): error TS2415: Class 'B5' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. @@ -30,7 +30,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B extends A { ~ !!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer3.ts:4:34: 'bar' is declared here. [x: number]: Base; // error @@ -58,7 +58,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 extends A { ~~ !!! error TS2415: Class 'B3' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'Base' is not assignable to type 'T'. !!! error TS2415: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. [x: number]: Base; // error @@ -67,7 +67,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B4 extends A { ~~ !!! error TS2415: Class 'B4' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'Derived' is not assignable to type 'T'. !!! error TS2415: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. [x: number]: Derived; // error @@ -76,7 +76,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B5 extends A { ~~ !!! error TS2415: Class 'B5' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'Derived2' is not assignable to type 'T'. !!! error TS2415: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. [x: number]: Derived2; // error diff --git a/tests/baselines/reference/subtypingWithNumericIndexer4.errors.txt b/tests/baselines/reference/subtypingWithNumericIndexer4.errors.txt index 21a6f22c4da4b..263f66d50e0e6 100644 --- a/tests/baselines/reference/subtypingWithNumericIndexer4.errors.txt +++ b/tests/baselines/reference/subtypingWithNumericIndexer4.errors.txt @@ -1,13 +1,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer4.ts(11,7): error TS2415: Class 'B' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'string' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer4.ts(20,11): error TS2415: Class 'B' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'string' is not assignable to type 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer4.ts(20,23): error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer4.ts(24,11): error TS2415: Class 'B3' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'number' index signatures are incompatible. Type 'string' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'. @@ -26,7 +26,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B extends A { ~ !!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'string' is not assignable to type 'Derived'. [x: number]: string; // error } @@ -39,7 +39,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B extends A { ~ !!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'string' is not assignable to type 'Base'. ~~~~ !!! error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. @@ -51,7 +51,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 extends A { ~~ !!! error TS2415: Class 'B3' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'number' index signatures are incompatible. !!! error TS2415: Type 'string' is not assignable to type 'T'. !!! error TS2415: 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'. [x: number]: string; // error diff --git a/tests/baselines/reference/subtypingWithNumericIndexer5.errors.txt b/tests/baselines/reference/subtypingWithNumericIndexer5.errors.txt index 897e76300e9e3..a35684b943f33 100644 --- a/tests/baselines/reference/subtypingWithNumericIndexer5.errors.txt +++ b/tests/baselines/reference/subtypingWithNumericIndexer5.errors.txt @@ -1,17 +1,17 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer5.ts(11,7): error TS2420: Class 'B' incorrectly implements interface 'A'. - Index signatures are incompatible. + 'string' and 'number' index signatures are incompatible. Type 'Base' is not assignable to type 'Derived'. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer5.ts(32,11): error TS2420: Class 'B3' incorrectly implements interface 'A'. - Index signatures are incompatible. + 'string' and 'number' index signatures are incompatible. Type 'Base' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer5.ts(36,11): error TS2420: Class 'B4' incorrectly implements interface 'A'. - Index signatures are incompatible. + 'string' and 'number' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer5.ts(40,11): error TS2420: Class 'B5' incorrectly implements interface 'A'. - Index signatures are incompatible. + 'string' and 'number' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. @@ -30,7 +30,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B implements A { ~ !!! error TS2420: Class 'B' incorrectly implements interface 'A'. -!!! error TS2420: Index signatures are incompatible. +!!! error TS2420: 'string' and 'number' index signatures are incompatible. !!! error TS2420: Type 'Base' is not assignable to type 'Derived'. !!! error TS2420: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithNumericIndexer5.ts:4:34: 'bar' is declared here. @@ -57,7 +57,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 implements A { ~~ !!! error TS2420: Class 'B3' incorrectly implements interface 'A'. -!!! error TS2420: Index signatures are incompatible. +!!! error TS2420: 'string' and 'number' index signatures are incompatible. !!! error TS2420: Type 'Base' is not assignable to type 'T'. !!! error TS2420: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. [x: string]: Base; // error @@ -66,7 +66,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B4 implements A { ~~ !!! error TS2420: Class 'B4' incorrectly implements interface 'A'. -!!! error TS2420: Index signatures are incompatible. +!!! error TS2420: 'string' and 'number' index signatures are incompatible. !!! error TS2420: Type 'Derived' is not assignable to type 'T'. !!! error TS2420: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. [x: string]: Derived; // error @@ -75,7 +75,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B5 implements A { ~~ !!! error TS2420: Class 'B5' incorrectly implements interface 'A'. -!!! error TS2420: Index signatures are incompatible. +!!! error TS2420: 'string' and 'number' index signatures are incompatible. !!! error TS2420: Type 'Derived2' is not assignable to type 'T'. !!! error TS2420: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. [x: string]: Derived2; // error diff --git a/tests/baselines/reference/subtypingWithStringIndexer.errors.txt b/tests/baselines/reference/subtypingWithStringIndexer.errors.txt index 80a1a6acfc043..89d152e4da109 100644 --- a/tests/baselines/reference/subtypingWithStringIndexer.errors.txt +++ b/tests/baselines/reference/subtypingWithStringIndexer.errors.txt @@ -1,9 +1,9 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer.ts(32,11): error TS2415: Class 'B3' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer.ts(36,11): error TS2415: Class 'B4' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. @@ -43,7 +43,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 extends A { ~~ !!! error TS2415: Class 'B3' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'Derived' is not assignable to type 'T'. !!! error TS2415: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. [x: string]: Derived; // error @@ -52,7 +52,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B4 extends A { ~~ !!! error TS2415: Class 'B4' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'Derived2' is not assignable to type 'T'. !!! error TS2415: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Base'. [x: string]: Derived2; // error diff --git a/tests/baselines/reference/subtypingWithStringIndexer2.errors.txt b/tests/baselines/reference/subtypingWithStringIndexer2.errors.txt index 5dfd4904ec31d..1025474d0b7a4 100644 --- a/tests/baselines/reference/subtypingWithStringIndexer2.errors.txt +++ b/tests/baselines/reference/subtypingWithStringIndexer2.errors.txt @@ -1,17 +1,17 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts(11,11): error TS2430: Interface 'B' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts(24,27): error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts(32,15): error TS2430: Interface 'B3' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts(36,15): error TS2430: Interface 'B4' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts(40,15): error TS2430: Interface 'B5' incorrectly extends interface 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. @@ -30,7 +30,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B extends A { ~ !!! error TS2430: Interface 'B' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'string' index signatures are incompatible. !!! error TS2430: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer2.ts:4:34: 'bar' is declared here. [x: string]: Base; // error @@ -58,7 +58,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B3 extends A { ~~ !!! error TS2430: Interface 'B3' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'string' index signatures are incompatible. !!! error TS2430: Type 'Base' is not assignable to type 'T'. !!! error TS2430: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. [x: string]: Base; // error @@ -67,7 +67,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B4 extends A { ~~ !!! error TS2430: Interface 'B4' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'string' index signatures are incompatible. !!! error TS2430: Type 'Derived' is not assignable to type 'T'. !!! error TS2430: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. [x: string]: Derived; // error @@ -76,7 +76,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW interface B5 extends A { ~~ !!! error TS2430: Interface 'B5' incorrectly extends interface 'A'. -!!! error TS2430: Index signatures are incompatible. +!!! error TS2430: 'string' index signatures are incompatible. !!! error TS2430: Type 'Derived2' is not assignable to type 'T'. !!! error TS2430: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. [x: string]: Derived2; // error diff --git a/tests/baselines/reference/subtypingWithStringIndexer3.errors.txt b/tests/baselines/reference/subtypingWithStringIndexer3.errors.txt index 936be924c0157..d5f6facc71ad6 100644 --- a/tests/baselines/reference/subtypingWithStringIndexer3.errors.txt +++ b/tests/baselines/reference/subtypingWithStringIndexer3.errors.txt @@ -1,17 +1,17 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts(11,7): error TS2415: Class 'B' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts(24,23): error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts(32,11): error TS2415: Class 'B3' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Base' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts(36,11): error TS2415: Class 'B4' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived' is not assignable to type 'T'. 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts(40,11): error TS2415: Class 'B5' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'Derived2' is not assignable to type 'T'. 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. @@ -30,7 +30,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B extends A { ~ !!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Property 'bar' is missing in type 'Base' but required in type 'Derived'. !!! related TS2728 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer3.ts:4:34: 'bar' is declared here. [x: string]: Base; // error @@ -58,7 +58,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 extends A { ~~ !!! error TS2415: Class 'B3' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'Base' is not assignable to type 'T'. !!! error TS2415: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'. [x: string]: Base; // error @@ -67,7 +67,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B4 extends A { ~~ !!! error TS2415: Class 'B4' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'Derived' is not assignable to type 'T'. !!! error TS2415: 'Derived' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived'. [x: string]: Derived; // error @@ -76,7 +76,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B5 extends A { ~~ !!! error TS2415: Class 'B5' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'Derived2' is not assignable to type 'T'. !!! error TS2415: 'Derived2' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Derived2'. [x: string]: Derived2; // error diff --git a/tests/baselines/reference/subtypingWithStringIndexer4.errors.txt b/tests/baselines/reference/subtypingWithStringIndexer4.errors.txt index 824200e9f0d2f..66aa8858ce891 100644 --- a/tests/baselines/reference/subtypingWithStringIndexer4.errors.txt +++ b/tests/baselines/reference/subtypingWithStringIndexer4.errors.txt @@ -1,13 +1,13 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer4.ts(11,7): error TS2415: Class 'B' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string' is not assignable to type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer4.ts(20,11): error TS2415: Class 'B' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string' is not assignable to type 'Base'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer4.ts(20,23): error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. Property 'bar' is missing in type 'Base' but required in type 'Derived'. tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingWithStringIndexer4.ts(24,11): error TS2415: Class 'B3' incorrectly extends base class 'A'. - Index signatures are incompatible. + 'string' index signatures are incompatible. Type 'string' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'. @@ -26,7 +26,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B extends A { ~ !!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'string' is not assignable to type 'Derived'. [x: string]: string; // error } @@ -39,7 +39,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B extends A { ~ !!! error TS2415: Class 'B' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'string' is not assignable to type 'Base'. ~~~~ !!! error TS2344: Type 'Base' does not satisfy the constraint 'Derived'. @@ -51,7 +51,7 @@ tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypingW class B3 extends A { ~~ !!! error TS2415: Class 'B3' incorrectly extends base class 'A'. -!!! error TS2415: Index signatures are incompatible. +!!! error TS2415: 'string' index signatures are incompatible. !!! error TS2415: Type 'string' is not assignable to type 'T'. !!! error TS2415: 'T' could be instantiated with an arbitrary type which could be unrelated to 'string'. [x: string]: string; // error From 077c9602afe8d3333352a20528f659be92b4e947 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 8 Jun 2021 10:37:31 -0700 Subject: [PATCH 35/56] Minor fix --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 711ab3e62cf00..873198e706ea3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -41134,7 +41134,7 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } const type = getTypeFromTypeNode(parameter.type); - if (someType(type, t => !!(t.flags & (TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.Instantiable)) && !isPatternLiteralType(type))) { + if (someType(type, t => !!(t.flags & (TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.Instantiable)) && !isPatternLiteralType(t))) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead); } if (!everyType(type, t => !!(t.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol | TypeFlags.TemplateLiteral)))) { From 96390cafb52e7bbaf95c642974b386698e1ab79e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 8 Jun 2021 10:37:43 -0700 Subject: [PATCH 36/56] Add tests --- .../types/members/indexSignatures1.ts | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 tests/cases/conformance/types/members/indexSignatures1.ts diff --git a/tests/cases/conformance/types/members/indexSignatures1.ts b/tests/cases/conformance/types/members/indexSignatures1.ts new file mode 100644 index 0000000000000..d63ac0268bc6c --- /dev/null +++ b/tests/cases/conformance/types/members/indexSignatures1.ts @@ -0,0 +1,154 @@ +// @strict: true +// @declaration: true +// @target: esnext + +// Symbol index signature checking + +const sym = Symbol(); + +function gg3(x: { [key: string]: string }, y: { [key: symbol]: string }, z: { [sym]: number }) { + x = z; + y = z; // Error +} + +// Overlapping index signatures + +function gg1(x: { [key: `a${string}`]: string, [key: `${string}a`]: string }, y: { [key: `a${string}a`]: string }) { + x = y; + y = x; +} + +interface IX { [key: `a${string}`]: string, [key: `${string}a`]: string } +interface IY { [key: `a${string}a`]: string } + +function gg2(x: IX, y: IY) { + x = y; // Error + y = x; +} + +// Intersection of multiple applicable index signatures + +declare let combo: { [x: `foo-${string}`]: 'a' | 'b' } & { [x: `${string}-bar`]: 'b' | 'c' }; +const x1 = combo['foo-test']; // 'a' | 'b' +const x2 = combo['test-bar']; // 'b' | 'c' +const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) + +// Property access on template pattern index signature + +declare let dom: { [x: `data${string}`]: string }; +const y1 = dom['data123']; +const y2 = dom.data123; + +// Excess property checking for template pattern index signature + +dom = { data123: 'hello' }; +dom = { date123: 'hello' }; // Error + +// Contextual typing by index signature with template literal pattern + +type Funcs = { + [key: `s${string}`]: (x: string) => void, + [key: `n${string}`]: (x: number) => void, +} + +const funcs: Funcs = { + sfoo: x => x.length, // x: string + nfoo: x => x * 2, // n: number +} + +// Duplicate index signature checking + +type Duplicates = { + [key: string | number]: any; // Error + [key: number | symbol]: any; // Error + [key: symbol | `foo${string}`]: any; // Error + [key: `foo${string}`]: any; // Error +} + +// Conflicting index signature checking + +type Conflicting = { + [key: `a${string}`]: 'a'; + [key: `${string}a`]: 'b'; + [key: `a${string}a`]: 'c'; // Error +} + +// Invalid index signatures + +type Invalid = { + [key: 'a' | 'b' | 'c']: string; // Error + [key: T | number]: string; // Error + [key: Error]: string; // Error +} + +// Repros from #1863 + +const system = Symbol('system'); +const SomeSytePlugin = Symbol('SomeSytePlugin'); + +interface Plugs { + [key: symbol]: (...args: any) => unknown; +} + +const plugins = { + "user": {} as Plugs, + [system]: {} as Plugs +}; + +plugins[system][SomeSytePlugin] = () => console.log('awsome'); +plugins[system][SomeSytePlugin](); + +var theAnswer: symbol = Symbol('secret'); +var obj = {} as Record; +obj[theAnswer] = 42; + +// Repro from #26470 + +const directive = Symbol('directive'); +declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; + +let case1 = foo({ + [directive]: (x: string) => 'str', + addOne: (x: number) => x + 1, + double: (x: number) => x + x, +}); + +let case2 = foo({ + addOne: (x: number) => x + 1, + double: (x: number) => x + x, + [directive]: (x: string) => 'str', +}); + +let case3 = foo({ + [directive]: 'str', + addOne: (x: number) => x + 1, + double: (x: number) => x + x, +}); + +// Repros from #42192 + +type Pseudo = `&:${string}`; + +const AmIPseudo1: Pseudo = '&:test'; +const AmIPseudo: Pseudo = '&'; // Error + +type PseudoDeclaration = { [key in Pseudo]: string }; + +const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error + +type FieldPattern = `/${string}`; + +const path1: FieldPattern = '/one'; +const path2: FieldPattern = 'two'; // Error + +type PathsObject = { [P in FieldPattern]: object; }; +const pathObject: PathsObject = 123; // Error + +type IdType = `${number}-${number}-${number}-${number}` +const id: IdType = '0000-0000-0000-0001'; + +type A = Record; + +const a: A = { [id]: 'test' } + +let aid = a[id]; From b7c9038a9e549887918fe210aceb92a3c1c46a9c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 8 Jun 2021 10:37:51 -0700 Subject: [PATCH 37/56] Accept new baselines --- .../reference/indexSignatures1.errors.txt | 218 +++++++++ tests/baselines/reference/indexSignatures1.js | 318 ++++++++++++ .../reference/indexSignatures1.symbols | 403 +++++++++++++++ .../reference/indexSignatures1.types | 461 ++++++++++++++++++ 4 files changed, 1400 insertions(+) create mode 100644 tests/baselines/reference/indexSignatures1.errors.txt create mode 100644 tests/baselines/reference/indexSignatures1.js create mode 100644 tests/baselines/reference/indexSignatures1.symbols create mode 100644 tests/baselines/reference/indexSignatures1.types diff --git a/tests/baselines/reference/indexSignatures1.errors.txt b/tests/baselines/reference/indexSignatures1.errors.txt new file mode 100644 index 0000000000000..20f117b5282d0 --- /dev/null +++ b/tests/baselines/reference/indexSignatures1.errors.txt @@ -0,0 +1,218 @@ +tests/cases/conformance/types/members/indexSignatures1.ts(7,5): error TS2322: Type '{ [sym]: number; }' is not assignable to type '{ [key: symbol]: string; }'. + Property '[sym]' is incompatible with index signature. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/members/indexSignatures1.ts(21,5): error TS2322: Type 'IY' is not assignable to type 'IX'. + Index signature for type '`a${string}`' is missing in type 'IY'. +tests/cases/conformance/types/members/indexSignatures1.ts(41,9): error TS2322: Type '{ date123: string; }' is not assignable to type '{ [x: `data${string}`]: string; }'. + Object literal may only specify known properties, and 'date123' does not exist in type '{ [x: `data${string}`]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(58,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/indexSignatures1.ts(59,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/indexSignatures1.ts(59,5): error TS2374: Duplicate index signature for type 'symbol'. +tests/cases/conformance/types/members/indexSignatures1.ts(60,5): error TS2374: Duplicate index signature for type '`foo${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(60,5): error TS2374: Duplicate index signature for type 'symbol'. +tests/cases/conformance/types/members/indexSignatures1.ts(61,5): error TS2374: Duplicate index signature for type '`foo${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(69,5): error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`${string}a`' index type '"b"'. +tests/cases/conformance/types/members/indexSignatures1.ts(69,5): error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`a${string}`' index type '"a"'. +tests/cases/conformance/types/members/indexSignatures1.ts(75,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. +tests/cases/conformance/types/members/indexSignatures1.ts(76,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. +tests/cases/conformance/types/members/indexSignatures1.ts(77,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. +tests/cases/conformance/types/members/indexSignatures1.ts(129,7): error TS2322: Type '"&"' is not assignable to type '`&:${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(133,35): error TS2322: Type '{ someKey: string; }' is not assignable to type 'PseudoDeclaration'. + Object literal may only specify known properties, and ''someKey'' does not exist in type 'PseudoDeclaration'. +tests/cases/conformance/types/members/indexSignatures1.ts(138,7): error TS2322: Type '"two"' is not assignable to type '`/${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(141,7): error TS2322: Type 'number' is not assignable to type 'PathsObject'. + + +==== tests/cases/conformance/types/members/indexSignatures1.ts (18 errors) ==== + // Symbol index signature checking + + const sym = Symbol(); + + function gg3(x: { [key: string]: string }, y: { [key: symbol]: string }, z: { [sym]: number }) { + x = z; + y = z; // Error + ~ +!!! error TS2322: Type '{ [sym]: number; }' is not assignable to type '{ [key: symbol]: string; }'. +!!! error TS2322: Property '[sym]' is incompatible with index signature. +!!! error TS2322: Type 'number' is not assignable to type 'string'. + } + + // Overlapping index signatures + + function gg1(x: { [key: `a${string}`]: string, [key: `${string}a`]: string }, y: { [key: `a${string}a`]: string }) { + x = y; + y = x; + } + + interface IX { [key: `a${string}`]: string, [key: `${string}a`]: string } + interface IY { [key: `a${string}a`]: string } + + function gg2(x: IX, y: IY) { + x = y; // Error + ~ +!!! error TS2322: Type 'IY' is not assignable to type 'IX'. +!!! error TS2322: Index signature for type '`a${string}`' is missing in type 'IY'. + y = x; + } + + // Intersection of multiple applicable index signatures + + declare let combo: { [x: `foo-${string}`]: 'a' | 'b' } & { [x: `${string}-bar`]: 'b' | 'c' }; + const x1 = combo['foo-test']; // 'a' | 'b' + const x2 = combo['test-bar']; // 'b' | 'c' + const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) + + // Property access on template pattern index signature + + declare let dom: { [x: `data${string}`]: string }; + const y1 = dom['data123']; + const y2 = dom.data123; + + // Excess property checking for template pattern index signature + + dom = { data123: 'hello' }; + dom = { date123: 'hello' }; // Error + ~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ date123: string; }' is not assignable to type '{ [x: `data${string}`]: string; }'. +!!! error TS2322: Object literal may only specify known properties, and 'date123' does not exist in type '{ [x: `data${string}`]: string; }'. + + // Contextual typing by index signature with template literal pattern + + type Funcs = { + [key: `s${string}`]: (x: string) => void, + [key: `n${string}`]: (x: number) => void, + } + + const funcs: Funcs = { + sfoo: x => x.length, // x: string + nfoo: x => x * 2, // n: number + } + + // Duplicate index signature checking + + type Duplicates = { + [key: string | number]: any; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. + [key: number | symbol]: any; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'number'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'symbol'. + [key: symbol | `foo${string}`]: any; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type '`foo${string}`'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type 'symbol'. + [key: `foo${string}`]: any; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2374: Duplicate index signature for type '`foo${string}`'. + } + + // Conflicting index signature checking + + type Conflicting = { + [key: `a${string}`]: 'a'; + [key: `${string}a`]: 'b'; + [key: `a${string}a`]: 'c'; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`${string}a`' index type '"b"'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`a${string}`' index type '"a"'. + } + + // Invalid index signatures + + type Invalid = { + [key: 'a' | 'b' | 'c']: string; // Error + ~~~ +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. + [key: T | number]: string; // Error + ~~~ +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. + [key: Error]: string; // Error + ~~~ +!!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. + } + + // Repros from #1863 + + const system = Symbol('system'); + const SomeSytePlugin = Symbol('SomeSytePlugin'); + + interface Plugs { + [key: symbol]: (...args: any) => unknown; + } + + const plugins = { + "user": {} as Plugs, + [system]: {} as Plugs + }; + + plugins[system][SomeSytePlugin] = () => console.log('awsome'); + plugins[system][SomeSytePlugin](); + + var theAnswer: symbol = Symbol('secret'); + var obj = {} as Record; + obj[theAnswer] = 42; + + // Repro from #26470 + + const directive = Symbol('directive'); + declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; + + let case1 = foo({ + [directive]: (x: string) => 'str', + addOne: (x: number) => x + 1, + double: (x: number) => x + x, + }); + + let case2 = foo({ + addOne: (x: number) => x + 1, + double: (x: number) => x + x, + [directive]: (x: string) => 'str', + }); + + let case3 = foo({ + [directive]: 'str', + addOne: (x: number) => x + 1, + double: (x: number) => x + x, + }); + + // Repros from #42192 + + type Pseudo = `&:${string}`; + + const AmIPseudo1: Pseudo = '&:test'; + const AmIPseudo: Pseudo = '&'; // Error + ~~~~~~~~~ +!!! error TS2322: Type '"&"' is not assignable to type '`&:${string}`'. + + type PseudoDeclaration = { [key in Pseudo]: string }; + + const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ someKey: string; }' is not assignable to type 'PseudoDeclaration'. +!!! error TS2322: Object literal may only specify known properties, and ''someKey'' does not exist in type 'PseudoDeclaration'. + + type FieldPattern = `/${string}`; + + const path1: FieldPattern = '/one'; + const path2: FieldPattern = 'two'; // Error + ~~~~~ +!!! error TS2322: Type '"two"' is not assignable to type '`/${string}`'. + + type PathsObject = { [P in FieldPattern]: object; }; + const pathObject: PathsObject = 123; // Error + ~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'PathsObject'. + + type IdType = `${number}-${number}-${number}-${number}` + const id: IdType = '0000-0000-0000-0001'; + + type A = Record; + + const a: A = { [id]: 'test' } + + let aid = a[id]; + \ No newline at end of file diff --git a/tests/baselines/reference/indexSignatures1.js b/tests/baselines/reference/indexSignatures1.js new file mode 100644 index 0000000000000..b69c891c52710 --- /dev/null +++ b/tests/baselines/reference/indexSignatures1.js @@ -0,0 +1,318 @@ +//// [indexSignatures1.ts] +// Symbol index signature checking + +const sym = Symbol(); + +function gg3(x: { [key: string]: string }, y: { [key: symbol]: string }, z: { [sym]: number }) { + x = z; + y = z; // Error +} + +// Overlapping index signatures + +function gg1(x: { [key: `a${string}`]: string, [key: `${string}a`]: string }, y: { [key: `a${string}a`]: string }) { + x = y; + y = x; +} + +interface IX { [key: `a${string}`]: string, [key: `${string}a`]: string } +interface IY { [key: `a${string}a`]: string } + +function gg2(x: IX, y: IY) { + x = y; // Error + y = x; +} + +// Intersection of multiple applicable index signatures + +declare let combo: { [x: `foo-${string}`]: 'a' | 'b' } & { [x: `${string}-bar`]: 'b' | 'c' }; +const x1 = combo['foo-test']; // 'a' | 'b' +const x2 = combo['test-bar']; // 'b' | 'c' +const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) + +// Property access on template pattern index signature + +declare let dom: { [x: `data${string}`]: string }; +const y1 = dom['data123']; +const y2 = dom.data123; + +// Excess property checking for template pattern index signature + +dom = { data123: 'hello' }; +dom = { date123: 'hello' }; // Error + +// Contextual typing by index signature with template literal pattern + +type Funcs = { + [key: `s${string}`]: (x: string) => void, + [key: `n${string}`]: (x: number) => void, +} + +const funcs: Funcs = { + sfoo: x => x.length, // x: string + nfoo: x => x * 2, // n: number +} + +// Duplicate index signature checking + +type Duplicates = { + [key: string | number]: any; // Error + [key: number | symbol]: any; // Error + [key: symbol | `foo${string}`]: any; // Error + [key: `foo${string}`]: any; // Error +} + +// Conflicting index signature checking + +type Conflicting = { + [key: `a${string}`]: 'a'; + [key: `${string}a`]: 'b'; + [key: `a${string}a`]: 'c'; // Error +} + +// Invalid index signatures + +type Invalid = { + [key: 'a' | 'b' | 'c']: string; // Error + [key: T | number]: string; // Error + [key: Error]: string; // Error +} + +// Repros from #1863 + +const system = Symbol('system'); +const SomeSytePlugin = Symbol('SomeSytePlugin'); + +interface Plugs { + [key: symbol]: (...args: any) => unknown; +} + +const plugins = { + "user": {} as Plugs, + [system]: {} as Plugs +}; + +plugins[system][SomeSytePlugin] = () => console.log('awsome'); +plugins[system][SomeSytePlugin](); + +var theAnswer: symbol = Symbol('secret'); +var obj = {} as Record; +obj[theAnswer] = 42; + +// Repro from #26470 + +const directive = Symbol('directive'); +declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; + +let case1 = foo({ + [directive]: (x: string) => 'str', + addOne: (x: number) => x + 1, + double: (x: number) => x + x, +}); + +let case2 = foo({ + addOne: (x: number) => x + 1, + double: (x: number) => x + x, + [directive]: (x: string) => 'str', +}); + +let case3 = foo({ + [directive]: 'str', + addOne: (x: number) => x + 1, + double: (x: number) => x + x, +}); + +// Repros from #42192 + +type Pseudo = `&:${string}`; + +const AmIPseudo1: Pseudo = '&:test'; +const AmIPseudo: Pseudo = '&'; // Error + +type PseudoDeclaration = { [key in Pseudo]: string }; + +const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error + +type FieldPattern = `/${string}`; + +const path1: FieldPattern = '/one'; +const path2: FieldPattern = 'two'; // Error + +type PathsObject = { [P in FieldPattern]: object; }; +const pathObject: PathsObject = 123; // Error + +type IdType = `${number}-${number}-${number}-${number}` +const id: IdType = '0000-0000-0000-0001'; + +type A = Record; + +const a: A = { [id]: 'test' } + +let aid = a[id]; + + +//// [indexSignatures1.js] +"use strict"; +// Symbol index signature checking +const sym = Symbol(); +function gg3(x, y, z) { + x = z; + y = z; // Error +} +// Overlapping index signatures +function gg1(x, y) { + x = y; + y = x; +} +function gg2(x, y) { + x = y; // Error + y = x; +} +const x1 = combo['foo-test']; // 'a' | 'b' +const x2 = combo['test-bar']; // 'b' | 'c' +const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) +const y1 = dom['data123']; +const y2 = dom.data123; +// Excess property checking for template pattern index signature +dom = { data123: 'hello' }; +dom = { date123: 'hello' }; // Error +const funcs = { + sfoo: x => x.length, + nfoo: x => x * 2, // n: number +}; +// Repros from #1863 +const system = Symbol('system'); +const SomeSytePlugin = Symbol('SomeSytePlugin'); +const plugins = { + "user": {}, + [system]: {} +}; +plugins[system][SomeSytePlugin] = () => console.log('awsome'); +plugins[system][SomeSytePlugin](); +var theAnswer = Symbol('secret'); +var obj = {}; +obj[theAnswer] = 42; +// Repro from #26470 +const directive = Symbol('directive'); +let case1 = foo({ + [directive]: (x) => 'str', + addOne: (x) => x + 1, + double: (x) => x + x, +}); +let case2 = foo({ + addOne: (x) => x + 1, + double: (x) => x + x, + [directive]: (x) => 'str', +}); +let case3 = foo({ + [directive]: 'str', + addOne: (x) => x + 1, + double: (x) => x + x, +}); +const AmIPseudo1 = '&:test'; +const AmIPseudo = '&'; // Error +const test = { 'someKey': 'someValue' }; // Error +const path1 = '/one'; +const path2 = 'two'; // Error +const pathObject = 123; // Error +const id = '0000-0000-0000-0001'; +const a = { [id]: 'test' }; +let aid = a[id]; + + +//// [indexSignatures1.d.ts] +declare const sym: unique symbol; +declare function gg3(x: { + [key: string]: string; +}, y: { + [key: symbol]: string; +}, z: { + [sym]: number; +}): void; +declare function gg1(x: { + [key: `a${string}`]: string; + [key: `${string}a`]: string; +}, y: { + [key: `a${string}a`]: string; +}): void; +interface IX { + [key: `a${string}`]: string; + [key: `${string}a`]: string; +} +interface IY { + [key: `a${string}a`]: string; +} +declare function gg2(x: IX, y: IY): void; +declare let combo: { + [x: `foo-${string}`]: 'a' | 'b'; +} & { + [x: `${string}-bar`]: 'b' | 'c'; +}; +declare const x1: "a" | "b"; +declare const x2: "b" | "c"; +declare const x3: "b"; +declare let dom: { + [x: `data${string}`]: string; +}; +declare const y1: string; +declare const y2: string; +declare type Funcs = { + [key: `s${string}`]: (x: string) => void; + [key: `n${string}`]: (x: number) => void; +}; +declare const funcs: Funcs; +declare type Duplicates = { + [key: string | number]: any; + [key: number | symbol]: any; + [key: symbol | `foo${string}`]: any; + [key: `foo${string}`]: any; +}; +declare type Conflicting = { + [key: `a${string}`]: 'a'; + [key: `${string}a`]: 'b'; + [key: `a${string}a`]: 'c'; +}; +declare type Invalid = { + [key: 'a' | 'b' | 'c']: string; + [key: T | number]: string; + [key: Error]: string; +}; +declare const system: unique symbol; +declare const SomeSytePlugin: unique symbol; +interface Plugs { + [key: symbol]: (...args: any) => unknown; +} +declare const plugins: { + user: Plugs; + [system]: Plugs; +}; +declare var theAnswer: symbol; +declare var obj: Record; +declare const directive: unique symbol; +declare function foo(options: { + [x in string]: (arg: TArg) => TRet; +} & { + [directive]?: TDir; +}): void; +declare let case1: void; +declare let case2: void; +declare let case3: void; +declare type Pseudo = `&:${string}`; +declare const AmIPseudo1: Pseudo; +declare const AmIPseudo: Pseudo; +declare type PseudoDeclaration = { + [key in Pseudo]: string; +}; +declare const test: PseudoDeclaration; +declare type FieldPattern = `/${string}`; +declare const path1: FieldPattern; +declare const path2: FieldPattern; +declare type PathsObject = { + [P in FieldPattern]: object; +}; +declare const pathObject: PathsObject; +declare type IdType = `${number}-${number}-${number}-${number}`; +declare const id: IdType; +declare type A = Record; +declare const a: A; +declare let aid: string; diff --git a/tests/baselines/reference/indexSignatures1.symbols b/tests/baselines/reference/indexSignatures1.symbols new file mode 100644 index 0000000000000..94f485b9d264e --- /dev/null +++ b/tests/baselines/reference/indexSignatures1.symbols @@ -0,0 +1,403 @@ +=== tests/cases/conformance/types/members/indexSignatures1.ts === +// Symbol index signature checking + +const sym = Symbol(); +>sym : Symbol(sym, Decl(indexSignatures1.ts, 2, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +function gg3(x: { [key: string]: string }, y: { [key: symbol]: string }, z: { [sym]: number }) { +>gg3 : Symbol(gg3, Decl(indexSignatures1.ts, 2, 21)) +>x : Symbol(x, Decl(indexSignatures1.ts, 4, 13)) +>key : Symbol(key, Decl(indexSignatures1.ts, 4, 19)) +>y : Symbol(y, Decl(indexSignatures1.ts, 4, 42)) +>key : Symbol(key, Decl(indexSignatures1.ts, 4, 49)) +>z : Symbol(z, Decl(indexSignatures1.ts, 4, 72)) +>[sym] : Symbol([sym], Decl(indexSignatures1.ts, 4, 77)) +>sym : Symbol(sym, Decl(indexSignatures1.ts, 2, 5)) + + x = z; +>x : Symbol(x, Decl(indexSignatures1.ts, 4, 13)) +>z : Symbol(z, Decl(indexSignatures1.ts, 4, 72)) + + y = z; // Error +>y : Symbol(y, Decl(indexSignatures1.ts, 4, 42)) +>z : Symbol(z, Decl(indexSignatures1.ts, 4, 72)) +} + +// Overlapping index signatures + +function gg1(x: { [key: `a${string}`]: string, [key: `${string}a`]: string }, y: { [key: `a${string}a`]: string }) { +>gg1 : Symbol(gg1, Decl(indexSignatures1.ts, 7, 1)) +>x : Symbol(x, Decl(indexSignatures1.ts, 11, 13)) +>key : Symbol(key, Decl(indexSignatures1.ts, 11, 19)) +>key : Symbol(key, Decl(indexSignatures1.ts, 11, 48)) +>y : Symbol(y, Decl(indexSignatures1.ts, 11, 77)) +>key : Symbol(key, Decl(indexSignatures1.ts, 11, 84)) + + x = y; +>x : Symbol(x, Decl(indexSignatures1.ts, 11, 13)) +>y : Symbol(y, Decl(indexSignatures1.ts, 11, 77)) + + y = x; +>y : Symbol(y, Decl(indexSignatures1.ts, 11, 77)) +>x : Symbol(x, Decl(indexSignatures1.ts, 11, 13)) +} + +interface IX { [key: `a${string}`]: string, [key: `${string}a`]: string } +>IX : Symbol(IX, Decl(indexSignatures1.ts, 14, 1)) +>key : Symbol(key, Decl(indexSignatures1.ts, 16, 16)) +>key : Symbol(key, Decl(indexSignatures1.ts, 16, 45)) + +interface IY { [key: `a${string}a`]: string } +>IY : Symbol(IY, Decl(indexSignatures1.ts, 16, 73)) +>key : Symbol(key, Decl(indexSignatures1.ts, 17, 16)) + +function gg2(x: IX, y: IY) { +>gg2 : Symbol(gg2, Decl(indexSignatures1.ts, 17, 45)) +>x : Symbol(x, Decl(indexSignatures1.ts, 19, 13)) +>IX : Symbol(IX, Decl(indexSignatures1.ts, 14, 1)) +>y : Symbol(y, Decl(indexSignatures1.ts, 19, 19)) +>IY : Symbol(IY, Decl(indexSignatures1.ts, 16, 73)) + + x = y; // Error +>x : Symbol(x, Decl(indexSignatures1.ts, 19, 13)) +>y : Symbol(y, Decl(indexSignatures1.ts, 19, 19)) + + y = x; +>y : Symbol(y, Decl(indexSignatures1.ts, 19, 19)) +>x : Symbol(x, Decl(indexSignatures1.ts, 19, 13)) +} + +// Intersection of multiple applicable index signatures + +declare let combo: { [x: `foo-${string}`]: 'a' | 'b' } & { [x: `${string}-bar`]: 'b' | 'c' }; +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) +>x : Symbol(x, Decl(indexSignatures1.ts, 26, 22)) +>x : Symbol(x, Decl(indexSignatures1.ts, 26, 60)) + +const x1 = combo['foo-test']; // 'a' | 'b' +>x1 : Symbol(x1, Decl(indexSignatures1.ts, 27, 5)) +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) + +const x2 = combo['test-bar']; // 'b' | 'c' +>x2 : Symbol(x2, Decl(indexSignatures1.ts, 28, 5)) +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) + +const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) +>x3 : Symbol(x3, Decl(indexSignatures1.ts, 29, 5)) +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) + +// Property access on template pattern index signature + +declare let dom: { [x: `data${string}`]: string }; +>dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) +>x : Symbol(x, Decl(indexSignatures1.ts, 33, 20)) + +const y1 = dom['data123']; +>y1 : Symbol(y1, Decl(indexSignatures1.ts, 34, 5)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) + +const y2 = dom.data123; +>y2 : Symbol(y2, Decl(indexSignatures1.ts, 35, 5)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) + +// Excess property checking for template pattern index signature + +dom = { data123: 'hello' }; +>dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) +>data123 : Symbol(data123, Decl(indexSignatures1.ts, 39, 7)) + +dom = { date123: 'hello' }; // Error +>dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) +>date123 : Symbol(date123, Decl(indexSignatures1.ts, 40, 7)) + +// Contextual typing by index signature with template literal pattern + +type Funcs = { +>Funcs : Symbol(Funcs, Decl(indexSignatures1.ts, 40, 27)) + + [key: `s${string}`]: (x: string) => void, +>key : Symbol(key, Decl(indexSignatures1.ts, 45, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 45, 26)) + + [key: `n${string}`]: (x: number) => void, +>key : Symbol(key, Decl(indexSignatures1.ts, 46, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 46, 26)) +} + +const funcs: Funcs = { +>funcs : Symbol(funcs, Decl(indexSignatures1.ts, 49, 5)) +>Funcs : Symbol(Funcs, Decl(indexSignatures1.ts, 40, 27)) + + sfoo: x => x.length, // x: string +>sfoo : Symbol(sfoo, Decl(indexSignatures1.ts, 49, 22)) +>x : Symbol(x, Decl(indexSignatures1.ts, 50, 9)) +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(indexSignatures1.ts, 50, 9)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + + nfoo: x => x * 2, // n: number +>nfoo : Symbol(nfoo, Decl(indexSignatures1.ts, 50, 24)) +>x : Symbol(x, Decl(indexSignatures1.ts, 51, 9)) +>x : Symbol(x, Decl(indexSignatures1.ts, 51, 9)) +} + +// Duplicate index signature checking + +type Duplicates = { +>Duplicates : Symbol(Duplicates, Decl(indexSignatures1.ts, 52, 1)) + + [key: string | number]: any; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 57, 5)) + + [key: number | symbol]: any; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 58, 5)) + + [key: symbol | `foo${string}`]: any; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 59, 5)) + + [key: `foo${string}`]: any; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 60, 5)) +} + +// Conflicting index signature checking + +type Conflicting = { +>Conflicting : Symbol(Conflicting, Decl(indexSignatures1.ts, 61, 1)) + + [key: `a${string}`]: 'a'; +>key : Symbol(key, Decl(indexSignatures1.ts, 66, 5)) + + [key: `${string}a`]: 'b'; +>key : Symbol(key, Decl(indexSignatures1.ts, 67, 5)) + + [key: `a${string}a`]: 'c'; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 68, 5)) +} + +// Invalid index signatures + +type Invalid = { +>Invalid : Symbol(Invalid, Decl(indexSignatures1.ts, 69, 1)) +>T : Symbol(T, Decl(indexSignatures1.ts, 73, 13)) + + [key: 'a' | 'b' | 'c']: string; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 74, 5)) + + [key: T | number]: string; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 75, 5)) +>T : Symbol(T, Decl(indexSignatures1.ts, 73, 13)) + + [key: Error]: string; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 76, 5)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +// Repros from #1863 + +const system = Symbol('system'); +>system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +const SomeSytePlugin = Symbol('SomeSytePlugin'); +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 82, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +interface Plugs { +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 82, 48)) + + [key: symbol]: (...args: any) => unknown; +>key : Symbol(key, Decl(indexSignatures1.ts, 85, 5)) +>args : Symbol(args, Decl(indexSignatures1.ts, 85, 20)) +} + +const plugins = { +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 88, 5)) + + "user": {} as Plugs, +>"user" : Symbol("user", Decl(indexSignatures1.ts, 88, 17)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 82, 48)) + + [system]: {} as Plugs +>[system] : Symbol([system], Decl(indexSignatures1.ts, 89, 24)) +>system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 82, 48)) + +}; + +plugins[system][SomeSytePlugin] = () => console.log('awsome'); +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 88, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 82, 5)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + +plugins[system][SomeSytePlugin](); +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 88, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 82, 5)) + +var theAnswer: symbol = Symbol('secret'); +>theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 96, 3)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +var obj = {} as Record; +>obj : Symbol(obj, Decl(indexSignatures1.ts, 97, 3)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +obj[theAnswer] = 42; +>obj : Symbol(obj, Decl(indexSignatures1.ts, 97, 3)) +>theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 96, 3)) + +// Repro from #26470 + +const directive = Symbol('directive'); +>directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; +>foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) +>TArg : Symbol(TArg, Decl(indexSignatures1.ts, 103, 21)) +>TRet : Symbol(TRet, Decl(indexSignatures1.ts, 103, 26)) +>TDir : Symbol(TDir, Decl(indexSignatures1.ts, 103, 32)) +>options : Symbol(options, Decl(indexSignatures1.ts, 103, 39)) +>x : Symbol(x, Decl(indexSignatures1.ts, 103, 51)) +>arg : Symbol(arg, Decl(indexSignatures1.ts, 103, 66)) +>TArg : Symbol(TArg, Decl(indexSignatures1.ts, 103, 21)) +>TRet : Symbol(TRet, Decl(indexSignatures1.ts, 103, 26)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 103, 90)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) +>TDir : Symbol(TDir, Decl(indexSignatures1.ts, 103, 32)) + +let case1 = foo({ +>case1 : Symbol(case1, Decl(indexSignatures1.ts, 105, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) + + [directive]: (x: string) => 'str', +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 105, 17)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 106, 18)) + + addOne: (x: number) => x + 1, +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 106, 38)) +>x : Symbol(x, Decl(indexSignatures1.ts, 107, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 107, 13)) + + double: (x: number) => x + x, +>double : Symbol(double, Decl(indexSignatures1.ts, 107, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 108, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 108, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 108, 13)) + +}); + +let case2 = foo({ +>case2 : Symbol(case2, Decl(indexSignatures1.ts, 111, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) + + addOne: (x: number) => x + 1, +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 111, 17)) +>x : Symbol(x, Decl(indexSignatures1.ts, 112, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 112, 13)) + + double: (x: number) => x + x, +>double : Symbol(double, Decl(indexSignatures1.ts, 112, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 113, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 113, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 113, 13)) + + [directive]: (x: string) => 'str', +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 113, 33)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 114, 18)) + +}); + +let case3 = foo({ +>case3 : Symbol(case3, Decl(indexSignatures1.ts, 117, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) + + [directive]: 'str', +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 117, 17)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) + + addOne: (x: number) => x + 1, +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 118, 23)) +>x : Symbol(x, Decl(indexSignatures1.ts, 119, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 119, 13)) + + double: (x: number) => x + x, +>double : Symbol(double, Decl(indexSignatures1.ts, 119, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 120, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 120, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 120, 13)) + +}); + +// Repros from #42192 + +type Pseudo = `&:${string}`; +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) + +const AmIPseudo1: Pseudo = '&:test'; +>AmIPseudo1 : Symbol(AmIPseudo1, Decl(indexSignatures1.ts, 127, 5)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) + +const AmIPseudo: Pseudo = '&'; // Error +>AmIPseudo : Symbol(AmIPseudo, Decl(indexSignatures1.ts, 128, 5)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) + +type PseudoDeclaration = { [key in Pseudo]: string }; +>PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 128, 30)) +>key : Symbol(key, Decl(indexSignatures1.ts, 130, 28)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) + +const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error +>test : Symbol(test, Decl(indexSignatures1.ts, 132, 5)) +>PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 128, 30)) +>'someKey' : Symbol('someKey', Decl(indexSignatures1.ts, 132, 33)) + +type FieldPattern = `/${string}`; +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) + +const path1: FieldPattern = '/one'; +>path1 : Symbol(path1, Decl(indexSignatures1.ts, 136, 5)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) + +const path2: FieldPattern = 'two'; // Error +>path2 : Symbol(path2, Decl(indexSignatures1.ts, 137, 5)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) + +type PathsObject = { [P in FieldPattern]: object; }; +>PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 137, 34)) +>P : Symbol(P, Decl(indexSignatures1.ts, 139, 22)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) + +const pathObject: PathsObject = 123; // Error +>pathObject : Symbol(pathObject, Decl(indexSignatures1.ts, 140, 5)) +>PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 137, 34)) + +type IdType = `${number}-${number}-${number}-${number}` +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 140, 36)) + +const id: IdType = '0000-0000-0000-0001'; +>id : Symbol(id, Decl(indexSignatures1.ts, 143, 5)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 140, 36)) + +type A = Record; +>A : Symbol(A, Decl(indexSignatures1.ts, 143, 41)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 140, 36)) + +const a: A = { [id]: 'test' } +>a : Symbol(a, Decl(indexSignatures1.ts, 147, 5)) +>A : Symbol(A, Decl(indexSignatures1.ts, 143, 41)) +>[id] : Symbol([id], Decl(indexSignatures1.ts, 147, 14)) +>id : Symbol(id, Decl(indexSignatures1.ts, 143, 5)) + +let aid = a[id]; +>aid : Symbol(aid, Decl(indexSignatures1.ts, 149, 3)) +>a : Symbol(a, Decl(indexSignatures1.ts, 147, 5)) +>id : Symbol(id, Decl(indexSignatures1.ts, 143, 5)) + diff --git a/tests/baselines/reference/indexSignatures1.types b/tests/baselines/reference/indexSignatures1.types new file mode 100644 index 0000000000000..ee53e028807d4 --- /dev/null +++ b/tests/baselines/reference/indexSignatures1.types @@ -0,0 +1,461 @@ +=== tests/cases/conformance/types/members/indexSignatures1.ts === +// Symbol index signature checking + +const sym = Symbol(); +>sym : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +function gg3(x: { [key: string]: string }, y: { [key: symbol]: string }, z: { [sym]: number }) { +>gg3 : (x: { [key: string]: string; }, y: { [key: symbol]: string; }, z: { [sym]: number;}) => void +>x : { [key: string]: string; } +>key : string +>y : { [key: symbol]: string; } +>key : symbol +>z : { [sym]: number; } +>[sym] : number +>sym : unique symbol + + x = z; +>x = z : { [sym]: number; } +>x : { [key: string]: string; } +>z : { [sym]: number; } + + y = z; // Error +>y = z : { [sym]: number; } +>y : { [key: symbol]: string; } +>z : { [sym]: number; } +} + +// Overlapping index signatures + +function gg1(x: { [key: `a${string}`]: string, [key: `${string}a`]: string }, y: { [key: `a${string}a`]: string }) { +>gg1 : (x: { [key: `a${string}`]: string; [key: `${string}a`]: string; }, y: { [key: `a${string}a`]: string; }) => void +>x : { [key: `a${string}`]: string; [key: `${string}a`]: string; } +>key : `a${string}` +>key : `${string}a` +>y : { [key: `a${string}a`]: string; } +>key : `a${string}a` + + x = y; +>x = y : { [key: `a${string}a`]: string; } +>x : { [key: `a${string}`]: string; [key: `${string}a`]: string; } +>y : { [key: `a${string}a`]: string; } + + y = x; +>y = x : { [key: `a${string}`]: string; [key: `${string}a`]: string; } +>y : { [key: `a${string}a`]: string; } +>x : { [key: `a${string}`]: string; [key: `${string}a`]: string; } +} + +interface IX { [key: `a${string}`]: string, [key: `${string}a`]: string } +>key : `a${string}` +>key : `${string}a` + +interface IY { [key: `a${string}a`]: string } +>key : `a${string}a` + +function gg2(x: IX, y: IY) { +>gg2 : (x: IX, y: IY) => void +>x : IX +>y : IY + + x = y; // Error +>x = y : IY +>x : IX +>y : IY + + y = x; +>y = x : IX +>y : IY +>x : IX +} + +// Intersection of multiple applicable index signatures + +declare let combo: { [x: `foo-${string}`]: 'a' | 'b' } & { [x: `${string}-bar`]: 'b' | 'c' }; +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>x : `foo-${string}` +>x : `${string}-bar` + +const x1 = combo['foo-test']; // 'a' | 'b' +>x1 : "a" | "b" +>combo['foo-test'] : "a" | "b" +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>'foo-test' : "foo-test" + +const x2 = combo['test-bar']; // 'b' | 'c' +>x2 : "b" | "c" +>combo['test-bar'] : "b" | "c" +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>'test-bar' : "test-bar" + +const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) +>x3 : "b" +>combo['foo-test-bar'] : "b" +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>'foo-test-bar' : "foo-test-bar" + +// Property access on template pattern index signature + +declare let dom: { [x: `data${string}`]: string }; +>dom : { [x: `data${string}`]: string; } +>x : `data${string}` + +const y1 = dom['data123']; +>y1 : string +>dom['data123'] : string +>dom : { [x: `data${string}`]: string; } +>'data123' : "data123" + +const y2 = dom.data123; +>y2 : string +>dom.data123 : string +>dom : { [x: `data${string}`]: string; } +>data123 : string + +// Excess property checking for template pattern index signature + +dom = { data123: 'hello' }; +>dom = { data123: 'hello' } : { data123: string; } +>dom : { [x: `data${string}`]: string; } +>{ data123: 'hello' } : { data123: string; } +>data123 : string +>'hello' : "hello" + +dom = { date123: 'hello' }; // Error +>dom = { date123: 'hello' } : { date123: string; } +>dom : { [x: `data${string}`]: string; } +>{ date123: 'hello' } : { date123: string; } +>date123 : string +>'hello' : "hello" + +// Contextual typing by index signature with template literal pattern + +type Funcs = { +>Funcs : Funcs + + [key: `s${string}`]: (x: string) => void, +>key : `s${string}` +>x : string + + [key: `n${string}`]: (x: number) => void, +>key : `n${string}` +>x : number +} + +const funcs: Funcs = { +>funcs : Funcs +>{ sfoo: x => x.length, // x: string nfoo: x => x * 2, // n: number} : { sfoo: (x: string) => number; nfoo: (x: number) => number; } + + sfoo: x => x.length, // x: string +>sfoo : (x: string) => number +>x => x.length : (x: string) => number +>x : string +>x.length : number +>x : string +>length : number + + nfoo: x => x * 2, // n: number +>nfoo : (x: number) => number +>x => x * 2 : (x: number) => number +>x : number +>x * 2 : number +>x : number +>2 : 2 +} + +// Duplicate index signature checking + +type Duplicates = { +>Duplicates : Duplicates + + [key: string | number]: any; // Error +>key : string | number + + [key: number | symbol]: any; // Error +>key : number | symbol + + [key: symbol | `foo${string}`]: any; // Error +>key : symbol | `foo${string}` + + [key: `foo${string}`]: any; // Error +>key : `foo${string}` +} + +// Conflicting index signature checking + +type Conflicting = { +>Conflicting : Conflicting + + [key: `a${string}`]: 'a'; +>key : `a${string}` + + [key: `${string}a`]: 'b'; +>key : `${string}a` + + [key: `a${string}a`]: 'c'; // Error +>key : `a${string}a` +} + +// Invalid index signatures + +type Invalid = { +>Invalid : Invalid + + [key: 'a' | 'b' | 'c']: string; // Error +>key : "a" | "b" | "c" + + [key: T | number]: string; // Error +>key : number | T + + [key: Error]: string; // Error +>key : Error +} + +// Repros from #1863 + +const system = Symbol('system'); +>system : unique symbol +>Symbol('system') : unique symbol +>Symbol : SymbolConstructor +>'system' : "system" + +const SomeSytePlugin = Symbol('SomeSytePlugin'); +>SomeSytePlugin : unique symbol +>Symbol('SomeSytePlugin') : unique symbol +>Symbol : SymbolConstructor +>'SomeSytePlugin' : "SomeSytePlugin" + +interface Plugs { + [key: symbol]: (...args: any) => unknown; +>key : symbol +>args : any +} + +const plugins = { +>plugins : { user: Plugs; [system]: Plugs; } +>{ "user": {} as Plugs, [system]: {} as Plugs} : { user: Plugs; [system]: Plugs; } + + "user": {} as Plugs, +>"user" : Plugs +>{} as Plugs : Plugs +>{} : {} + + [system]: {} as Plugs +>[system] : Plugs +>system : unique symbol +>{} as Plugs : Plugs +>{} : {} + +}; + +plugins[system][SomeSytePlugin] = () => console.log('awsome'); +>plugins[system][SomeSytePlugin] = () => console.log('awsome') : () => void +>plugins[system][SomeSytePlugin] : (...args: any) => unknown +>plugins[system] : Plugs +>plugins : { user: Plugs; [system]: Plugs; } +>system : unique symbol +>SomeSytePlugin : unique symbol +>() => console.log('awsome') : () => void +>console.log('awsome') : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>'awsome' : "awsome" + +plugins[system][SomeSytePlugin](); +>plugins[system][SomeSytePlugin]() : unknown +>plugins[system][SomeSytePlugin] : (...args: any) => unknown +>plugins[system] : Plugs +>plugins : { user: Plugs; [system]: Plugs; } +>system : unique symbol +>SomeSytePlugin : unique symbol + +var theAnswer: symbol = Symbol('secret'); +>theAnswer : symbol +>Symbol('secret') : symbol +>Symbol : SymbolConstructor +>'secret' : "secret" + +var obj = {} as Record; +>obj : Record +>{} as Record : Record +>{} : {} + +obj[theAnswer] = 42; +>obj[theAnswer] = 42 : 42 +>obj[theAnswer] : number +>obj : Record +>theAnswer : symbol +>42 : 42 + +// Repro from #26470 + +const directive = Symbol('directive'); +>directive : unique symbol +>Symbol('directive') : unique symbol +>Symbol : SymbolConstructor +>'directive' : "directive" + +declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; +>foo : (options: { [x: string]: (arg: TArg) => TRet; } & { [directive]?: TDir | undefined; }) => void +>options : { [x: string]: (arg: TArg) => TRet; } & { [directive]?: TDir | undefined; } +>arg : TArg +>[directive] : TDir | undefined +>directive : unique symbol + +let case1 = foo({ +>case1 : void +>foo({ [directive]: (x: string) => 'str', addOne: (x: number) => x + 1, double: (x: number) => x + x,}) : void +>foo : (options: { [x: string]: (arg: TArg) => TRet; } & { [directive]?: TDir | undefined; }) => void +>{ [directive]: (x: string) => 'str', addOne: (x: number) => x + 1, double: (x: number) => x + x,} : { [directive]: (x: string) => "str"; addOne: (x: number) => number; double: (x: number) => number; } + + [directive]: (x: string) => 'str', +>[directive] : (x: string) => "str" +>directive : unique symbol +>(x: string) => 'str' : (x: string) => "str" +>x : string +>'str' : "str" + + addOne: (x: number) => x + 1, +>addOne : (x: number) => number +>(x: number) => x + 1 : (x: number) => number +>x : number +>x + 1 : number +>x : number +>1 : 1 + + double: (x: number) => x + x, +>double : (x: number) => number +>(x: number) => x + x : (x: number) => number +>x : number +>x + x : number +>x : number +>x : number + +}); + +let case2 = foo({ +>case2 : void +>foo({ addOne: (x: number) => x + 1, double: (x: number) => x + x, [directive]: (x: string) => 'str',}) : void +>foo : (options: { [x: string]: (arg: TArg) => TRet; } & { [directive]?: TDir | undefined; }) => void +>{ addOne: (x: number) => x + 1, double: (x: number) => x + x, [directive]: (x: string) => 'str',} : { addOne: (x: number) => number; double: (x: number) => number; [directive]: (x: string) => "str"; } + + addOne: (x: number) => x + 1, +>addOne : (x: number) => number +>(x: number) => x + 1 : (x: number) => number +>x : number +>x + 1 : number +>x : number +>1 : 1 + + double: (x: number) => x + x, +>double : (x: number) => number +>(x: number) => x + x : (x: number) => number +>x : number +>x + x : number +>x : number +>x : number + + [directive]: (x: string) => 'str', +>[directive] : (x: string) => "str" +>directive : unique symbol +>(x: string) => 'str' : (x: string) => "str" +>x : string +>'str' : "str" + +}); + +let case3 = foo({ +>case3 : void +>foo({ [directive]: 'str', addOne: (x: number) => x + 1, double: (x: number) => x + x,}) : void +>foo : (options: { [x: string]: (arg: TArg) => TRet; } & { [directive]?: TDir | undefined; }) => void +>{ [directive]: 'str', addOne: (x: number) => x + 1, double: (x: number) => x + x,} : { [directive]: string; addOne: (x: number) => number; double: (x: number) => number; } + + [directive]: 'str', +>[directive] : string +>directive : unique symbol +>'str' : "str" + + addOne: (x: number) => x + 1, +>addOne : (x: number) => number +>(x: number) => x + 1 : (x: number) => number +>x : number +>x + 1 : number +>x : number +>1 : 1 + + double: (x: number) => x + x, +>double : (x: number) => number +>(x: number) => x + x : (x: number) => number +>x : number +>x + x : number +>x : number +>x : number + +}); + +// Repros from #42192 + +type Pseudo = `&:${string}`; +>Pseudo : `&:${string}` + +const AmIPseudo1: Pseudo = '&:test'; +>AmIPseudo1 : `&:${string}` +>'&:test' : "&:test" + +const AmIPseudo: Pseudo = '&'; // Error +>AmIPseudo : `&:${string}` +>'&' : "&" + +type PseudoDeclaration = { [key in Pseudo]: string }; +>PseudoDeclaration : PseudoDeclaration + +const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error +>test : PseudoDeclaration +>{ 'someKey' : 'someValue' } : { someKey: string; } +>'someKey' : string +>'someValue' : "someValue" + +type FieldPattern = `/${string}`; +>FieldPattern : `/${string}` + +const path1: FieldPattern = '/one'; +>path1 : `/${string}` +>'/one' : "/one" + +const path2: FieldPattern = 'two'; // Error +>path2 : `/${string}` +>'two' : "two" + +type PathsObject = { [P in FieldPattern]: object; }; +>PathsObject : PathsObject + +const pathObject: PathsObject = 123; // Error +>pathObject : PathsObject +>123 : 123 + +type IdType = `${number}-${number}-${number}-${number}` +>IdType : `${number}-${number}-${number}-${number}` + +const id: IdType = '0000-0000-0000-0001'; +>id : `${number}-${number}-${number}-${number}` +>'0000-0000-0000-0001' : "0000-0000-0000-0001" + +type A = Record; +>A : A + +const a: A = { [id]: 'test' } +>a : A +>{ [id]: 'test' } : { [x: string]: string; } +>[id] : string +>id : `${number}-${number}-${number}-${number}` +>'test' : "test" + +let aid = a[id]; +>aid : string +>a[id] : string +>a : A +>id : `${number}-${number}-${number}-${number}` + From a92a41b5965ab48c81e15d878122271256881561 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 9 Jun 2021 11:16:31 -0700 Subject: [PATCH 38/56] Add optimized findApplicableIndexInfoForName --- src/compiler/checker.ts | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f7e47aabe3adb..e23c90b1b921b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12014,6 +12014,25 @@ namespace ts { undefined; } + function findApplicableIndexInfoForName(indexInfos: readonly IndexInfo[], name: __String) { + // We optimize for cases where we have no template literal index signatures as it is somewhat expensive + // to obtain the literal type for a name and check for assignability. + let stringIndexInfo: IndexInfo | undefined; + for (const info of indexInfos) { + const keyType = info.keyType; + if (keyType === stringType) { + stringIndexInfo = info; + } + else if (keyType === numberType && isNumericLiteralName(name)) { + return info; + } + else if (keyType.flags & TypeFlags.TemplateLiteral) { + return findApplicableIndexInfo(indexInfos, getLiteralType(unescapeLeadingUnderscores(name))); + } + } + return stringIndexInfo; + } + function isApplicableIndexType(source: Type, target: Type) { // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index // signature applies to types assignable to 'number' and numeric string literal types. @@ -12055,7 +12074,7 @@ namespace ts { } function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined { - return getApplicableIndexInfo(type, getLiteralType(unescapeLeadingUnderscores(name))); + return findApplicableIndexInfoForName(getIndexInfosOfType(type), name); } // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual @@ -25331,17 +25350,12 @@ namespace ts { return restType; } } - return getIndexTypeOfContextualType(type, getLiteralType(unescapeLeadingUnderscores(name))); + return findApplicableIndexInfoForName(getIndexInfosOfStructuredType(t), name)?.type; } return undefined; }, /*noReductions*/ true); } - function getIndexTypeOfContextualType(type: Type, keyType: Type) { - // We avoid calling getApplicableIndexInfo here because it performs potentially expensive intersection reduction. - return mapType(type, t => findApplicableIndexInfo(getIndexInfosOfStructuredType(t), keyType)?.type, /*noReductions*/ true); - } - // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one // exists. Otherwise, it is the type of the string index signature in T, if one exists. @@ -25366,13 +25380,13 @@ namespace ts { // For a (non-symbol) computed property, there is no reason to look up the name // in the type. It will just be "__computed", which does not appear in any // SymbolTable. - const symbolName = getSymbolOfNode(element).escapedName; - const propertyType = getTypeOfPropertyOfContextualType(type, symbolName); - if (propertyType) { - return propertyType; - } + return getTypeOfPropertyOfContextualType(type, getSymbolOfNode(element).escapedName); + } + if (element.name) { + const nameType = getLiteralTypeFromPropertyName(element.name); + // We avoid calling getApplicableIndexInfo here because it performs potentially expensive intersection reduction. + return mapType(type, t => findApplicableIndexInfo(getIndexInfosOfStructuredType(t), nameType)?.type, /*noReductions*/ true); } - return element.name && getIndexTypeOfContextualType(type, getLiteralTypeFromPropertyName(element.name)); } return undefined; } From 8dd8e38172c10a81a978ff1d2137bd1ff040f08e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 9 Jun 2021 11:16:47 -0700 Subject: [PATCH 39/56] Accept new baselines --- tests/baselines/reference/variadicTuples1.errors.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 809a12df2c3ed..485bdc6f4d05a 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -33,7 +33,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. - Type '"2"' is not assignable to type '"0" | "1" | keyof T[]'. + Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. Type at position 0 in source is not compatible with type at position 0 in target. @@ -298,7 +298,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Typ k3 = '2'; // Error ~~ !!! error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. -!!! error TS2322: Type '"2"' is not assignable to type '"0" | "1" | keyof T[]'. +!!! error TS2322: Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. } // Inference between variadic tuple types From 9e3f8cef44176fb7c7ff1b00e3c6ad92df5e9ab9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 9 Jun 2021 13:41:20 -0700 Subject: [PATCH 40/56] Another place we don't need to obtain literal type for property name --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e23c90b1b921b..8aae078631381 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11748,7 +11748,7 @@ namespace ts { } } else if (isUnion) { - const indexInfo = !isLateBoundName(name) && getApplicableIndexInfo(type, getLiteralType(isNumericLiteralName(name) ? +name : unescapeLeadingUnderscores(name))); + const indexInfo = !isLateBoundName(name) && getApplicableIndexInfoForName(type, name); if (indexInfo) { checkFlags |= CheckFlags.WritePartial | (indexInfo.isReadonly ? CheckFlags.Readonly : 0); indexTypes = append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type); From a98ff6d1cf3263fc72d0f1fe8ea3998d2524cc61 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 9 Jun 2021 13:41:29 -0700 Subject: [PATCH 41/56] Accept new baselines --- tests/baselines/reference/keyofAndIndexedAccess.types | 6 +++--- tests/baselines/reference/keyofAndIndexedAccessErrors.types | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 47a7cbfdbd635..893669d0c2b91 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -58,10 +58,10 @@ type K00 = keyof any; // string >K00 : string | number | symbol type K01 = keyof string; // "toString" | "charAt" | ... ->K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" +>K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "valueOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ... ->K02 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" +>K02 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" type K03 = keyof boolean; // "valueOf" >K03 : "valueOf" @@ -98,7 +98,7 @@ type K14 = keyof Object; // "constructor" | "toString" | ... >K14 : keyof Object type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... ->K15 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" +>K15 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... >K16 : keyof [string, number] diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 6fb2b69bfad91..27f0642094e45 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -26,19 +26,19 @@ type T01 = keyof Object; >T01 : keyof Object type T02 = keyof keyof Object; ->T02 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" +>T02 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" type T03 = keyof keyof keyof Object; >T03 : "toString" | "valueOf" type T04 = keyof keyof keyof keyof Object; ->T04 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" +>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" type T05 = keyof keyof keyof keyof keyof Object; >T05 : "toString" | "valueOf" type T06 = keyof keyof keyof keyof keyof keyof Object; ->T06 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" +>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" type T10 = Shape["name"]; >T10 : string From 8b2098d9bd6f4b8427f8c6d21df4b9c9b84d0964 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 9 Jun 2021 21:36:05 -0700 Subject: [PATCH 42/56] Don't create literal types that are going to be discarded --- src/compiler/checker.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8aae078631381..1286d2adb652b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14396,13 +14396,12 @@ namespace ts { if (includeNonPublic || !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { let type = getSymbolLinks(getLateBoundSymbol(prop)).nameType; if (!type) { - if (prop.escapedName === InternalSymbolName.Default) { - type = getLiteralType("default"); - } - else { - const name = prop.valueDeclaration && getNameOfDeclaration(prop.valueDeclaration) as PropertyName; - type = name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getLiteralType(symbolName(prop)) : undefined); + const name = getNameOfDeclaration(prop.valueDeclaration) as PropertyName; + if (name && (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral) && !(include & TypeFlags.StringLiteral)) { + return neverType; } + type = prop.escapedName === InternalSymbolName.Default ? getLiteralType("default") : + name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getLiteralType(symbolName(prop)) : undefined); } if (type && type.flags & include) { return type; @@ -14413,7 +14412,8 @@ namespace ts { function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeOrigin: boolean) { const origin = includeOrigin && (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference) || type.aliasSymbol) ? createOriginIndexType(type) : undefined; - const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, include)); + const propInclude = include & TypeFlags.String && getIndexInfoOfType(type, stringType) ? include & ~TypeFlags.StringLiteral : include; + const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, propInclude)); const indexKeyTypes = map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && info.keyType.flags & include ? info.keyType === stringType && include & TypeFlags.Number ? stringOrNumberType : info.keyType : neverType); return getUnionType(concatenate(propertyTypes, indexKeyTypes), UnionReduction.Literal, From d357fa0e48827a9fd861525b42ab6ec3dae7aea9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 10 Jun 2021 10:54:36 -0700 Subject: [PATCH 43/56] Individual maps for string, number, bigint, and enum literal types --- src/compiler/checker.ts | 139 +++++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 66 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1286d2adb652b..db4b698c4af7e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -715,7 +715,10 @@ namespace ts { const tupleTypes = new Map(); const unionTypes = new Map(); const intersectionTypes = new Map(); - const literalTypes = new Map(); + const stringLiteralTypes = new Map(); + const numberLiteralTypes = new Map(); + const bigIntLiteralTypes = new Map(); + const enumLiteralTypes = new Map(); const indexedAccessTypes = new Map(); const templateLiteralTypes = new Map(); const stringMappingTypes = new Map(); @@ -929,9 +932,9 @@ namespace ts { let lastFlowNodeReachable: boolean; let flowTypeCache: Type[] | undefined; - const emptyStringType = getLiteralType(""); - const zeroType = getLiteralType(0); - const zeroBigIntType = getLiteralType({ negative: false, base10Value: "0" }); + const emptyStringType = getStringLiteralType(""); + const zeroType = getNumberLiteralType(0); + const zeroBigIntType = getBigIntLiteralType({ negative: false, base10Value: "0" }); const resolutionTargets: TypeSystemEntity[] = []; const resolutionResults: boolean[] = []; @@ -3856,7 +3859,7 @@ namespace ts { } function createTypeofType() { - return getUnionType(arrayFrom(typeofEQFacts.keys(), getLiteralType)); + return getUnionType(arrayFrom(typeofEQFacts.keys(), getStringLiteralType)); } function createTypeParameter(symbol?: Symbol) { @@ -8306,7 +8309,7 @@ namespace ts { createArrayType(elementType); } else if (isArrayLikeType(parentType)) { - const indexType = getLiteralType(index); + const indexType = getNumberLiteralType(index); const accessFlags = AccessFlags.ExpressionPosition | (hasDefaultValue(declaration) ? AccessFlags.NoTupleBoundsCheck : 0); const declaredType = getIndexedAccessTypeOrUndefined(parentType, indexType, accessFlags, declaration.name) || errorType; type = getFlowTypeOfDestructuring(declaration, declaredType); @@ -9955,7 +9958,7 @@ namespace ts { if (declaration.kind === SyntaxKind.EnumDeclaration) { for (const member of (declaration as EnumDeclaration).members) { const value = getEnumMemberValue(member); - const memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); + const memberType = getFreshTypeOfLiteralType(getEnumLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member))); getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; memberTypeList.push(getRegularTypeOfLiteralType(memberType)); } @@ -10982,7 +10985,7 @@ namespace ts { // map type.indexType to 0 // map type.objectType to `[TReplacement]` // thus making the indexed access `[TReplacement][0]` or `TReplacement` - return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getLiteralType(0), createTupleType([replacement])])); + return instantiateType(instantiable, createTypeMapper([type.indexType, type.objectType], [getNumberLiteralType(0), createTupleType([replacement])])); } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { @@ -12027,7 +12030,7 @@ namespace ts { return info; } else if (keyType.flags & TypeFlags.TemplateLiteral) { - return findApplicableIndexInfo(indexInfos, getLiteralType(unescapeLeadingUnderscores(name))); + return findApplicableIndexInfo(indexInfos, getStringLiteralType(unescapeLeadingUnderscores(name))); } } return stringIndexInfo; @@ -13555,7 +13558,7 @@ namespace ts { } else { const literalTypes = []; - for (let i = minLength; i <= arity; i++) literalTypes.push(getLiteralType(i)); + for (let i = minLength; i <= arity; i++) literalTypes.push(getNumberLiteralType(i)); lengthSymbol.type = getUnionType(literalTypes); } properties.push(lengthSymbol); @@ -13689,7 +13692,7 @@ namespace ts { } function getKnownKeysOfTupleType(type: TupleTypeReference) { - return getUnionType(append(arrayOf(type.target.fixedLength, i => getLiteralType("" + i)), + return getUnionType(append(arrayOf(type.target.fixedLength, i => getStringLiteralType("" + i)), getIndexType(type.target.readonly ? globalReadonlyArrayType : globalArrayType))); } @@ -14381,17 +14384,10 @@ namespace ts { if (isPrivateIdentifier(name)) { return neverType; } - return isIdentifier(name) ? getLiteralType(unescapeLeadingUnderscores(name.escapedText)) : + return isIdentifier(name) ? getStringLiteralType(unescapeLeadingUnderscores(name.escapedText)) : getRegularTypeOfLiteralType(isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name)); } - function getBigIntLiteralType(node: BigIntLiteral): LiteralType { - return getLiteralType({ - negative: false, - base10Value: parsePseudoBigInt(node.text) - }); - } - function getLiteralTypeFromProperty(prop: Symbol, include: TypeFlags, includeNonPublic?: boolean) { if (includeNonPublic || !(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { let type = getSymbolLinks(getLateBoundSymbol(prop)).nameType; @@ -14400,8 +14396,8 @@ namespace ts { if (name && (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral) && !(include & TypeFlags.StringLiteral)) { return neverType; } - type = prop.escapedName === InternalSymbolName.Default ? getLiteralType("default") : - name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getLiteralType(symbolName(prop)) : undefined); + type = prop.escapedName === InternalSymbolName.Default ? getStringLiteralType("default") : + name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getStringLiteralType(symbolName(prop)) : undefined); } if (type && type.flags & include) { return type; @@ -14495,7 +14491,7 @@ namespace ts { return stringType; } if (newTypes.length === 0) { - return getLiteralType(text); + return getStringLiteralType(text); } newTexts.push(text); if (every(newTexts, t => t === "") && every(newTypes, t => !!(t.flags & TypeFlags.String))) { @@ -14551,7 +14547,7 @@ namespace ts { function getStringMappingType(symbol: Symbol, type: Type): Type { return type.flags & (TypeFlags.Union | TypeFlags.Never) ? mapType(type, t => getStringMappingType(symbol, t)) : isGenericIndexType(type) ? getStringMappingTypeForGenericType(symbol, type) : - type.flags & TypeFlags.StringLiteral ? getLiteralType(applyStringMapping(symbol, (type as StringLiteralType).value)) : + type.flags & TypeFlags.StringLiteral ? getStringLiteralType(applyStringMapping(symbol, (type as StringLiteralType).value)) : type; } @@ -15553,18 +15549,18 @@ namespace ts { return info.isReadonly !== readonly ? createIndexInfo(info.keyType, info.type, readonly, info.declaration) : info; } - function createLiteralType(flags: TypeFlags, value: string | number | PseudoBigInt, symbol: Symbol | undefined) { + function createLiteralType(flags: TypeFlags, value: string | number | PseudoBigInt, symbol?: Symbol, regularType?: LiteralType) { const type = createType(flags) as LiteralType; type.symbol = symbol!; type.value = value; + type.regularType = regularType || type; return type; } function getFreshTypeOfLiteralType(type: Type): Type { if (type.flags & TypeFlags.Literal) { if (!(type as LiteralType).freshType) { - const freshType = createLiteralType(type.flags, (type as LiteralType).value, (type as LiteralType).symbol); - freshType.regularType = type as LiteralType; + const freshType = createLiteralType(type.flags, (type as LiteralType).value, (type as LiteralType).symbol, type as LiteralType); freshType.freshType = freshType; (type as LiteralType).freshType = freshType; } @@ -15583,24 +15579,32 @@ namespace ts { return !!(type.flags & TypeFlags.Literal) && (type as LiteralType).freshType === type; } - function getLiteralType(value: string): StringLiteralType; - function getLiteralType(value: string | number | PseudoBigInt, enumId?: number, symbol?: Symbol): LiteralType; - function getLiteralType(value: string | number | PseudoBigInt, enumId?: number, symbol?: Symbol) { - // We store all literal types in a single map with keys of the form '#NNN' and '@SSS', - // where NNN is the text representation of a numeric literal and SSS are the characters - // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where - // EEE is a unique id for the containing enum type. - const qualifier = typeof value === "number" ? "#" : typeof value === "string" ? "@" : "n"; - const key = (enumId ? enumId : "") + qualifier + (typeof value === "object" ? pseudoBigIntToString(value) : value); - let type = literalTypes.get(key); - if (!type) { - const flags = (typeof value === "number" ? TypeFlags.NumberLiteral : - typeof value === "string" ? TypeFlags.StringLiteral : TypeFlags.BigIntLiteral) | - (enumId ? TypeFlags.EnumLiteral : 0); - literalTypes.set(key, type = createLiteralType(flags, value, symbol)); - type.regularType = type; - } - return type; + function getStringLiteralType(value: string): StringLiteralType { + let type; + return stringLiteralTypes.get(value) || + (stringLiteralTypes.set(value, type = createLiteralType(TypeFlags.StringLiteral, value) as StringLiteralType), type); + } + + function getNumberLiteralType(value: number): NumberLiteralType { + let type; + return numberLiteralTypes.get(value) || + (numberLiteralTypes.set(value, type = createLiteralType(TypeFlags.NumberLiteral, value) as NumberLiteralType), type); + } + + function getBigIntLiteralType(value: PseudoBigInt): BigIntLiteralType { + let type; + const key = pseudoBigIntToString(value); + return bigIntLiteralTypes.get(key) || + (bigIntLiteralTypes.set(key, type = createLiteralType(TypeFlags.BigIntLiteral, value) as BigIntLiteralType), type); + } + + function getEnumLiteralType(value: string | number, enumId: number, symbol: Symbol): LiteralType { + let type; + const qualifier = typeof value === "string" ? "@" : "#"; + const key = enumId + qualifier + value; + const flags = TypeFlags.EnumLiteral | (typeof value === "string" ? TypeFlags.StringLiteral : TypeFlags.NumberLiteral); + return enumLiteralTypes.get(key) || + (enumLiteralTypes.set(key, type = createLiteralType(flags, value, symbol)), type); } function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type { @@ -16147,7 +16151,7 @@ namespace ts { function instantiateMappedTupleType(tupleType: TupleTypeReference, mappedType: MappedType, mapper: TypeMapper) { const elementFlags = tupleType.target.elementFlags; const elementTypes = map(getTypeArguments(tupleType), (_, i) => - instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), !!(elementFlags[i] & ElementFlags.Optional), mapper)); + instantiateMappedTypeTemplate(mappedType, getStringLiteralType("" + i), !!(elementFlags[i] & ElementFlags.Optional), mapper)); const modifiers = getMappedTypeModifiers(mappedType); const newTupleModifiers = modifiers & MappedTypeModifiers.IncludeOptional ? map(elementFlags, f => f & ElementFlags.Required ? ElementFlags.Optional : f) : modifiers & MappedTypeModifiers.ExcludeOptional ? map(elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) : @@ -16769,7 +16773,7 @@ namespace ts { if (!length(node.properties)) return; for (const prop of node.properties) { if (isJsxSpreadAttribute(prop)) continue; - yield { errorNode: prop.name, innerExpression: prop.initializer, nameType: getLiteralType(idText(prop.name)) }; + yield { errorNode: prop.name, innerExpression: prop.initializer, nameType: getStringLiteralType(idText(prop.name)) }; } } @@ -16778,7 +16782,7 @@ namespace ts { let memberOffset = 0; for (let i = 0; i < node.children.length; i++) { const child = node.children[i]; - const nameType = getLiteralType(i - memberOffset); + const nameType = getNumberLiteralType(i - memberOffset); const elem = getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic); if (elem) { yield elem; @@ -16824,7 +16828,7 @@ namespace ts { const containingElement = node.parent.parent; const childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node)); const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName); - const childrenNameType = getLiteralType(childrenPropName); + const childrenNameType = getStringLiteralType(childrenPropName); const childrenTargetType = getIndexedAccessType(target, childrenNameType); const validChildren = getSemanticJsxChildren(containingElement.children); if (!length(validChildren)) { @@ -16890,7 +16894,7 @@ namespace ts { const tagNameText = getTextOfNode(node.parent.tagName); const childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node)); const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName); - const childrenTargetType = getIndexedAccessType(target, getLiteralType(childrenPropName)); + const childrenTargetType = getIndexedAccessType(target, getStringLiteralType(childrenPropName)); const diagnostic = Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2; invalidTextDiagnostic = { ...diagnostic, key: "!!ALREADY FORMATTED!!", message: formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) }; } @@ -16906,7 +16910,7 @@ namespace ts { if (isTupleLikeType(target) && !getPropertyOfType(target, ("" + i) as __String)) continue; const elem = node.elements[i]; if (isOmittedExpression(elem)) continue; - const nameType = getLiteralType(i); + const nameType = getNumberLiteralType(i); yield { errorNode: elem, innerExpression: elem, nameType }; } } @@ -21082,7 +21086,7 @@ namespace ts { } function addMatch(s: number, p: number) { const matchType = s === seg ? - getLiteralType(getSourceText(s).slice(pos, p)) : + getStringLiteralType(getSourceText(s).slice(pos, p)) : getTemplateLiteralType( [sourceTexts[seg].slice(pos), ...sourceTexts.slice(seg + 1, s), getSourceText(s).slice(0, p)], sourceTypes.slice(seg, s)); @@ -25191,7 +25195,7 @@ namespace ts { } const restIndex = signature.parameters.length - 1; return signatureHasRestParameter(signature) && argIndex >= restIndex ? - getIndexedAccessType(getTypeOfSymbol(signature.parameters[restIndex]), getLiteralType(argIndex - restIndex), AccessFlags.Contextual) : + getIndexedAccessType(getTypeOfSymbol(signature.parameters[restIndex]), getNumberLiteralType(argIndex - restIndex), AccessFlags.Contextual) : getTypeAtPosition(signature, argIndex); } @@ -25334,7 +25338,7 @@ namespace ts { if (isGenericMappedType(t)) { const constraint = getConstraintTypeFromMappedType(t); const constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint; - const propertyNameType = getLiteralType(unescapeLeadingUnderscores(name)); + const propertyNameType = getStringLiteralType(unescapeLeadingUnderscores(name)); if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) { return substituteIndexedMappedType(t, propertyNameType); } @@ -25422,7 +25426,7 @@ namespace ts { const childFieldType = getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName); return childFieldType && (realChildren.length === 1 ? childFieldType : mapType(childFieldType, t => { if (isArrayLikeType(t)) { - return getIndexedAccessType(t, getLiteralType(childIndex)); + return getIndexedAccessType(t, getNumberLiteralType(childIndex)); } else { return t; @@ -28309,7 +28313,7 @@ namespace ts { } } else { - const contextualType = getIndexedAccessType(restType, getLiteralType(i - index), AccessFlags.Contextual); + const contextualType = getIndexedAccessType(restType, getNumberLiteralType(i - index), AccessFlags.Contextual); const argType = checkExpressionWithContextualType(arg, contextualType, context, checkMode); const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping); types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); @@ -30108,7 +30112,7 @@ namespace ts { const memberTable = createSymbolTable(); const newSymbol = createSymbol(SymbolFlags.Alias, InternalSymbolName.Default); newSymbol.parent = originalSymbol; - newSymbol.nameType = getLiteralType("default"); + newSymbol.nameType = getStringLiteralType("default"); newSymbol.target = resolveSymbol(symbol); memberTable.set(InternalSymbolName.Default, newSymbol); const anonymousSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type); @@ -30340,7 +30344,7 @@ namespace ts { const restType = getTypeOfSymbol(signature.parameters[paramCount]); const index = pos - paramCount; if (!isTupleType(restType) || restType.target.hasRestElement || index < restType.target.fixedLength) { - return getIndexedAccessType(restType, getLiteralType(index)); + return getIndexedAccessType(restType, getNumberLiteralType(index)); } } return undefined; @@ -31278,14 +31282,14 @@ namespace ts { case SyntaxKind.NumericLiteral: switch (node.operator) { case SyntaxKind.MinusToken: - return getFreshTypeOfLiteralType(getLiteralType(-(node.operand as NumericLiteral).text)); + return getFreshTypeOfLiteralType(getNumberLiteralType(-(node.operand as NumericLiteral).text)); case SyntaxKind.PlusToken: - return getFreshTypeOfLiteralType(getLiteralType(+(node.operand as NumericLiteral).text)); + return getFreshTypeOfLiteralType(getNumberLiteralType(+(node.operand as NumericLiteral).text)); } break; case SyntaxKind.BigIntLiteral: if (node.operator === SyntaxKind.MinusToken) { - return getFreshTypeOfLiteralType(getLiteralType({ + return getFreshTypeOfLiteralType(getBigIntLiteralType({ negative: true, base10Value: parsePseudoBigInt((node.operand as BigIntLiteral).text) })); @@ -31551,7 +31555,7 @@ namespace ts { const element = elements[elementIndex]; if (element.kind !== SyntaxKind.OmittedExpression) { if (element.kind !== SyntaxKind.SpreadElement) { - const indexType = getLiteralType(elementIndex); + const indexType = getNumberLiteralType(elementIndex); if (isArrayLikeType(sourceType)) { // We create a synthetic expression so that getIndexedAccessType doesn't get confused // when the element is a SyntaxKind.ElementAccessExpression. @@ -32822,13 +32826,16 @@ namespace ts { return nullWideningType; case SyntaxKind.NoSubstitutionTemplateLiteral: case SyntaxKind.StringLiteral: - return getFreshTypeOfLiteralType(getLiteralType((node as StringLiteralLike).text)); + return getFreshTypeOfLiteralType(getStringLiteralType((node as StringLiteralLike).text)); case SyntaxKind.NumericLiteral: checkGrammarNumericLiteral(node as NumericLiteral); - return getFreshTypeOfLiteralType(getLiteralType(+(node as NumericLiteral).text)); + return getFreshTypeOfLiteralType(getNumberLiteralType(+(node as NumericLiteral).text)); case SyntaxKind.BigIntLiteral: checkGrammarBigIntLiteral(node as BigIntLiteral); - return getFreshTypeOfLiteralType(getBigIntLiteralType(node as BigIntLiteral)); + return getFreshTypeOfLiteralType(getBigIntLiteralType({ + negative: false, + base10Value: parsePseudoBigInt((node as BigIntLiteral).text) + })); case SyntaxKind.TrueKeyword: return trueType; case SyntaxKind.FalseKeyword: @@ -39652,10 +39659,10 @@ namespace ts { const name = element.name!; switch (name.kind) { case SyntaxKind.Identifier: - return getLiteralType(idText(name)); + return getStringLiteralType(idText(name)); case SyntaxKind.NumericLiteral: case SyntaxKind.StringLiteral: - return getLiteralType(name.text); + return getStringLiteralType(name.text); case SyntaxKind.ComputedPropertyName: const nameType = checkComputedPropertyName(name); return isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike) ? nameType : stringType; From cfd67e63449afea82187ade8bc5be9d84aff38de Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 11 Jun 2021 08:03:26 -0700 Subject: [PATCH 44/56] Remove ineffective optimizations --- src/compiler/checker.ts | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db4b698c4af7e..6b9f4bf0af66d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12017,25 +12017,6 @@ namespace ts { undefined; } - function findApplicableIndexInfoForName(indexInfos: readonly IndexInfo[], name: __String) { - // We optimize for cases where we have no template literal index signatures as it is somewhat expensive - // to obtain the literal type for a name and check for assignability. - let stringIndexInfo: IndexInfo | undefined; - for (const info of indexInfos) { - const keyType = info.keyType; - if (keyType === stringType) { - stringIndexInfo = info; - } - else if (keyType === numberType && isNumericLiteralName(name)) { - return info; - } - else if (keyType.flags & TypeFlags.TemplateLiteral) { - return findApplicableIndexInfo(indexInfos, getStringLiteralType(unescapeLeadingUnderscores(name))); - } - } - return stringIndexInfo; - } - function isApplicableIndexType(source: Type, target: Type) { // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index // signature applies to types assignable to 'number' and numeric string literal types. @@ -12077,7 +12058,7 @@ namespace ts { } function getApplicableIndexInfoForName(type: Type, name: __String): IndexInfo | undefined { - return findApplicableIndexInfoForName(getIndexInfosOfType(type), name); + return getApplicableIndexInfo(type, getStringLiteralType(unescapeLeadingUnderscores(name))); } // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual @@ -14393,9 +14374,6 @@ namespace ts { let type = getSymbolLinks(getLateBoundSymbol(prop)).nameType; if (!type) { const name = getNameOfDeclaration(prop.valueDeclaration) as PropertyName; - if (name && (name.kind === SyntaxKind.Identifier || name.kind === SyntaxKind.StringLiteral) && !(include & TypeFlags.StringLiteral)) { - return neverType; - } type = prop.escapedName === InternalSymbolName.Default ? getStringLiteralType("default") : name && getLiteralTypeFromPropertyName(name) || (!isKnownSymbol(prop) ? getStringLiteralType(symbolName(prop)) : undefined); } @@ -14408,8 +14386,7 @@ namespace ts { function getLiteralTypeFromProperties(type: Type, include: TypeFlags, includeOrigin: boolean) { const origin = includeOrigin && (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference) || type.aliasSymbol) ? createOriginIndexType(type) : undefined; - const propInclude = include & TypeFlags.String && getIndexInfoOfType(type, stringType) ? include & ~TypeFlags.StringLiteral : include; - const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, propInclude)); + const propertyTypes = map(getPropertiesOfType(type), prop => getLiteralTypeFromProperty(prop, include)); const indexKeyTypes = map(getIndexInfosOfType(type), info => info !== enumNumberIndexInfo && info.keyType.flags & include ? info.keyType === stringType && include & TypeFlags.Number ? stringOrNumberType : info.keyType : neverType); return getUnionType(concatenate(propertyTypes, indexKeyTypes), UnionReduction.Literal, @@ -25354,7 +25331,7 @@ namespace ts { return restType; } } - return findApplicableIndexInfoForName(getIndexInfosOfStructuredType(t), name)?.type; + return findApplicableIndexInfo(getIndexInfosOfStructuredType(t), getStringLiteralType(unescapeLeadingUnderscores(name)))?.type; } return undefined; }, /*noReductions*/ true); From e80704158b19355740ef6835a8447435a5a717e8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 11 Jun 2021 08:03:36 -0700 Subject: [PATCH 45/56] Accept new baselines --- tests/baselines/reference/keyofAndIndexedAccess.types | 6 +++--- tests/baselines/reference/keyofAndIndexedAccessErrors.types | 6 +++--- tests/baselines/reference/variadicTuples1.errors.txt | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 893669d0c2b91..47a7cbfdbd635 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -58,10 +58,10 @@ type K00 = keyof any; // string >K00 : string | number | symbol type K01 = keyof string; // "toString" | "charAt" | ... ->K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "valueOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ... ->K02 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" +>K02 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" type K03 = keyof boolean; // "valueOf" >K03 : "valueOf" @@ -98,7 +98,7 @@ type K14 = keyof Object; // "constructor" | "toString" | ... >K14 : keyof Object type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... ->K15 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" +>K15 : "toString" | "toLocaleString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... >K16 : keyof [string, number] diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 27f0642094e45..6fb2b69bfad91 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -26,19 +26,19 @@ type T01 = keyof Object; >T01 : keyof Object type T02 = keyof keyof Object; ->T02 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T02 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type T03 = keyof keyof keyof Object; >T03 : "toString" | "valueOf" type T04 = keyof keyof keyof keyof Object; ->T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T04 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type T05 = keyof keyof keyof keyof keyof Object; >T05 : "toString" | "valueOf" type T06 = keyof keyof keyof keyof keyof keyof Object; ->T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T06 : number | "length" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type T10 = Shape["name"]; >T10 : string diff --git a/tests/baselines/reference/variadicTuples1.errors.txt b/tests/baselines/reference/variadicTuples1.errors.txt index 485bdc6f4d05a..809a12df2c3ed 100644 --- a/tests/baselines/reference/variadicTuples1.errors.txt +++ b/tests/baselines/reference/variadicTuples1.errors.txt @@ -33,7 +33,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(191,5): error TS2322: Typ Type 'T' is not assignable to type 'U'. 'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'readonly string[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(203,5): error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. - Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. + Type '"2"' is not assignable to type '"0" | "1" | keyof T[]'. tests/cases/conformance/types/tuple/variadicTuples1.ts(357,26): error TS2322: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Type '[false, false]' is not assignable to type '[...number[], boolean]'. Type at position 0 in source is not compatible with type at position 0 in target. @@ -298,7 +298,7 @@ tests/cases/conformance/types/tuple/variadicTuples1.ts(397,7): error TS2322: Typ k3 = '2'; // Error ~~ !!! error TS2322: Type 'string' is not assignable to type 'keyof [1, 2, ...T]'. -!!! error TS2322: Type '"2"' is not assignable to type '"0" | keyof T[] | "1"'. +!!! error TS2322: Type '"2"' is not assignable to type '"0" | "1" | keyof T[]'. } // Inference between variadic tuple types From 5354b39c1c1c0a195fa3b2d9c2d082cf3491a526 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 15 Jun 2021 12:19:53 -0700 Subject: [PATCH 46/56] Permit intersections as key types in index signatures --- src/compiler/checker.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6b9f4bf0af66d..4698ed83eb852 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11126,7 +11126,7 @@ namespace ts { members.set(propName, prop); } } - else if (propNameType.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number | TypeFlags.Enum | TypeFlags.ESSymbol) || isPatternLiteralType(propNameType)) { + else if (isValidIndexKeyType(propNameType) || propNameType.flags & (TypeFlags.Any | TypeFlags.Enum)) { const indexKeyType = propNameType.flags & (TypeFlags.Any | TypeFlags.String) ? stringType : propNameType.flags & (TypeFlags.Number | TypeFlags.Enum) ? numberType : propNameType; @@ -12646,8 +12646,9 @@ namespace ts { return emptyArray; } - function isValidIndexKeyType(type: Type) { - return !!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol)) || isPatternLiteralType(type); + function isValidIndexKeyType(type: Type): boolean { + return !!(type.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol)) || isPatternLiteralType(type) || + !!(type.flags & TypeFlags.Intersection) && !isGenericIndexType(type) && !isGenericObjectType(type) && some((type as IntersectionType).types, isValidIndexKeyType); } function getConstraintDeclaration(type: TypeParameter): TypeNode | undefined { @@ -41166,10 +41167,10 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } const type = getTypeFromTypeNode(parameter.type); - if (someType(type, t => !!(t.flags & (TypeFlags.StringOrNumberLiteralOrUnique | TypeFlags.Instantiable)) && !isPatternLiteralType(t))) { + if (someType(type, t => !!(t.flags & TypeFlags.StringOrNumberLiteralOrUnique)) || isGenericIndexType(type) || isGenericObjectType(type)) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead); } - if (!everyType(type, t => !!(t.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.ESSymbol | TypeFlags.TemplateLiteral)))) { + if (!everyType(type, isValidIndexKeyType)) { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_symbol_or_a_template_literal_type); } if (!node.type) { From 4d0a3e0ec63e4613cdb2510872d94375771d1bd7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 15 Jun 2021 14:06:27 -0700 Subject: [PATCH 47/56] Index expression in element access is template literal context --- src/compiler/checker.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4698ed83eb852..4fe5df09a0301 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32328,6 +32328,12 @@ namespace ts { return getUnionType([type1, type2], UnionReduction.Subtype); } + function isTemplateLiteralContext(node: Node): boolean { + const parent = node.parent; + return isParenthesizedExpression(parent) && isTemplateLiteralContext(parent) || + isElementAccessExpression(parent) && parent.argumentExpression === node; + } + function checkTemplateExpression(node: TemplateExpression): Type { const texts = [node.head.text]; const types = []; @@ -32339,7 +32345,7 @@ namespace ts { texts.push(span.literal.text); types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType); } - return isConstContext(node) || someType(getContextualType(node) || unknownType, isTemplateLiteralContextualType) ? getTemplateLiteralType(texts, types) : stringType; + return isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node) || unknownType, isTemplateLiteralContextualType) ? getTemplateLiteralType(texts, types) : stringType; } function isTemplateLiteralContextualType(type: Type): boolean { From 00c7549e7b43c7a1b7650416e51db8a4766cbfa0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 15 Jun 2021 14:06:34 -0700 Subject: [PATCH 48/56] Add tests --- .../types/members/indexSignatures1.ts | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/cases/conformance/types/members/indexSignatures1.ts b/tests/cases/conformance/types/members/indexSignatures1.ts index d63ac0268bc6c..e2b41df793c1e 100644 --- a/tests/cases/conformance/types/members/indexSignatures1.ts +++ b/tests/cases/conformance/types/members/indexSignatures1.ts @@ -33,6 +33,18 @@ const x1 = combo['foo-test']; // 'a' | 'b' const x2 = combo['test-bar']; // 'b' | 'c' const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) +declare var str: string; + +const x4 = combo[`foo-${str}`]; +const x5 = combo[`${str}-bar`]; +const x6 = combo[`foo-${str}-bar`]; + +declare let combo2: { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string }; + +const x7 = combo2['axxxbyyyc']; +const x8 = combo2['ayyyxxxbc']; +const x9 = combo2['axxxbbbyc']; // Error + // Property access on template pattern index signature declare let dom: { [x: `data${string}`]: string }; @@ -79,8 +91,52 @@ type Invalid = { [key: 'a' | 'b' | 'c']: string; // Error [key: T | number]: string; // Error [key: Error]: string; // Error + [key: T & string]: string; // Error } +// Intersections in index signatures + +type Tag1 = { __tag1__: void }; +type Tag2 = { __tag2__: void }; + +type TaggedString1 = string & Tag1; +type TaggedString2 = string & Tag2; + +declare let obj1: { [key: TaggedString1]: string }; +declare let obj2: { [key: TaggedString2]: string }; +declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; +declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; + +declare let s0: string; +declare let s1: TaggedString1; +declare let s2: TaggedString2; +declare let s3: TaggedString1 | TaggedString2; +declare let s4: TaggedString1 & TaggedString2; + +obj1[s0]; // Error +obj1[s1]; +obj1[s2]; // Error +obj1[s3]; // Error +obj1[s4]; + +obj2[s0]; // Error +obj2[s1]; +obj2[s2]; +obj2[s3]; // Error +obj2[s4]; + +obj3[s0]; // Error +obj3[s1]; +obj3[s2]; +obj3[s3]; +obj3[s4]; + +obj4[s0]; // Error +obj4[s1]; // Error +obj4[s2]; // Error +obj4[s3]; // Error +obj4[s4]; + // Repros from #1863 const system = Symbol('system'); From 7a5ec8d8c4ad82a32acaaac036f9450fdd00ee95 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 15 Jun 2021 14:08:03 -0700 Subject: [PATCH 49/56] Accept new baselines --- .../reference/indexSignatures1.errors.txt | 139 +++++- tests/baselines/reference/indexSignatures1.js | 118 +++++ .../reference/indexSignatures1.symbols | 459 ++++++++++++------ .../reference/indexSignatures1.types | 196 ++++++++ 4 files changed, 755 insertions(+), 157 deletions(-) diff --git a/tests/baselines/reference/indexSignatures1.errors.txt b/tests/baselines/reference/indexSignatures1.errors.txt index 20f117b5282d0..1777166005b46 100644 --- a/tests/baselines/reference/indexSignatures1.errors.txt +++ b/tests/baselines/reference/indexSignatures1.errors.txt @@ -3,27 +3,45 @@ tests/cases/conformance/types/members/indexSignatures1.ts(7,5): error TS2322: Ty Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/members/indexSignatures1.ts(21,5): error TS2322: Type 'IY' is not assignable to type 'IX'. Index signature for type '`a${string}`' is missing in type 'IY'. -tests/cases/conformance/types/members/indexSignatures1.ts(41,9): error TS2322: Type '{ date123: string; }' is not assignable to type '{ [x: `data${string}`]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(42,12): error TS7053: Element implicitly has an 'any' type because expression of type '"axxxbbbyc"' can't be used to index type '{ [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; }'. + Property 'axxxbbbyc' does not exist on type '{ [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(53,9): error TS2322: Type '{ date123: string; }' is not assignable to type '{ [x: `data${string}`]: string; }'. Object literal may only specify known properties, and 'date123' does not exist in type '{ [x: `data${string}`]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(58,5): error TS2374: Duplicate index signature for type 'number'. -tests/cases/conformance/types/members/indexSignatures1.ts(59,5): error TS2374: Duplicate index signature for type 'number'. -tests/cases/conformance/types/members/indexSignatures1.ts(59,5): error TS2374: Duplicate index signature for type 'symbol'. -tests/cases/conformance/types/members/indexSignatures1.ts(60,5): error TS2374: Duplicate index signature for type '`foo${string}`'. -tests/cases/conformance/types/members/indexSignatures1.ts(60,5): error TS2374: Duplicate index signature for type 'symbol'. -tests/cases/conformance/types/members/indexSignatures1.ts(61,5): error TS2374: Duplicate index signature for type '`foo${string}`'. -tests/cases/conformance/types/members/indexSignatures1.ts(69,5): error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`${string}a`' index type '"b"'. -tests/cases/conformance/types/members/indexSignatures1.ts(69,5): error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`a${string}`' index type '"a"'. -tests/cases/conformance/types/members/indexSignatures1.ts(75,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. -tests/cases/conformance/types/members/indexSignatures1.ts(76,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. -tests/cases/conformance/types/members/indexSignatures1.ts(77,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. -tests/cases/conformance/types/members/indexSignatures1.ts(129,7): error TS2322: Type '"&"' is not assignable to type '`&:${string}`'. -tests/cases/conformance/types/members/indexSignatures1.ts(133,35): error TS2322: Type '{ someKey: string; }' is not assignable to type 'PseudoDeclaration'. +tests/cases/conformance/types/members/indexSignatures1.ts(70,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/indexSignatures1.ts(71,5): error TS2374: Duplicate index signature for type 'number'. +tests/cases/conformance/types/members/indexSignatures1.ts(71,5): error TS2374: Duplicate index signature for type 'symbol'. +tests/cases/conformance/types/members/indexSignatures1.ts(72,5): error TS2374: Duplicate index signature for type '`foo${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(72,5): error TS2374: Duplicate index signature for type 'symbol'. +tests/cases/conformance/types/members/indexSignatures1.ts(73,5): error TS2374: Duplicate index signature for type '`foo${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(81,5): error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`${string}a`' index type '"b"'. +tests/cases/conformance/types/members/indexSignatures1.ts(81,5): error TS2413: '`a${string}a`' index type '"c"' is not assignable to '`a${string}`' index type '"a"'. +tests/cases/conformance/types/members/indexSignatures1.ts(87,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. +tests/cases/conformance/types/members/indexSignatures1.ts(88,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. +tests/cases/conformance/types/members/indexSignatures1.ts(89,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. +tests/cases/conformance/types/members/indexSignatures1.ts(90,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. +tests/cases/conformance/types/members/indexSignatures1.ts(112,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; }'. + No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(114,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(115,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(118,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString2]: string; }'. + No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(119,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(121,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(124,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. + No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(130,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. + No index signature with a parameter of type 'string' was found on type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(131,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(132,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(133,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(185,7): error TS2322: Type '"&"' is not assignable to type '`&:${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(189,35): error TS2322: Type '{ someKey: string; }' is not assignable to type 'PseudoDeclaration'. Object literal may only specify known properties, and ''someKey'' does not exist in type 'PseudoDeclaration'. -tests/cases/conformance/types/members/indexSignatures1.ts(138,7): error TS2322: Type '"two"' is not assignable to type '`/${string}`'. -tests/cases/conformance/types/members/indexSignatures1.ts(141,7): error TS2322: Type 'number' is not assignable to type 'PathsObject'. +tests/cases/conformance/types/members/indexSignatures1.ts(194,7): error TS2322: Type '"two"' is not assignable to type '`/${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(197,7): error TS2322: Type 'number' is not assignable to type 'PathsObject'. -==== tests/cases/conformance/types/members/indexSignatures1.ts (18 errors) ==== +==== tests/cases/conformance/types/members/indexSignatures1.ts (31 errors) ==== // Symbol index signature checking const sym = Symbol(); @@ -62,6 +80,21 @@ tests/cases/conformance/types/members/indexSignatures1.ts(141,7): error TS2322: const x2 = combo['test-bar']; // 'b' | 'c' const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) + declare var str: string; + + const x4 = combo[`foo-${str}`]; + const x5 = combo[`${str}-bar`]; + const x6 = combo[`foo-${str}-bar`]; + + declare let combo2: { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string }; + + const x7 = combo2['axxxbyyyc']; + const x8 = combo2['ayyyxxxbc']; + const x9 = combo2['axxxbbbyc']; // Error + ~~~~~~~~~~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"axxxbbbyc"' can't be used to index type '{ [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; }'. +!!! error TS7053: Property 'axxxbbbyc' does not exist on type '{ [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; }'. + // Property access on template pattern index signature declare let dom: { [x: `data${string}`]: string }; @@ -133,8 +166,80 @@ tests/cases/conformance/types/members/indexSignatures1.ts(141,7): error TS2322: [key: Error]: string; // Error ~~~ !!! error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. + [key: T & string]: string; // Error + ~~~ +!!! error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. } + // Intersections in index signatures + + type Tag1 = { __tag1__: void }; + type Tag2 = { __tag2__: void }; + + type TaggedString1 = string & Tag1; + type TaggedString2 = string & Tag2; + + declare let obj1: { [key: TaggedString1]: string }; + declare let obj2: { [key: TaggedString2]: string }; + declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; + declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; + + declare let s0: string; + declare let s1: TaggedString1; + declare let s2: TaggedString2; + declare let s3: TaggedString1 | TaggedString2; + declare let s4: TaggedString1 & TaggedString2; + + obj1[s0]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; }'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; }'. + obj1[s1]; + obj1[s2]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. + obj1[s3]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. + obj1[s4]; + + obj2[s0]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString2]: string; }'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString2]: string; }'. + obj2[s1]; + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: TaggedString2]: string; }'. + obj2[s2]; + obj2[s3]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString2]: string; }'. + obj2[s4]; + + obj3[s0]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. + obj3[s1]; + obj3[s2]; + obj3[s3]; + obj3[s4]; + + obj4[s0]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: string & Tag1 & Tag2]: string; }'. + obj4[s1]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. + obj4[s2]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. + obj4[s3]; // Error + ~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. + obj4[s4]; + // Repros from #1863 const system = Symbol('system'); diff --git a/tests/baselines/reference/indexSignatures1.js b/tests/baselines/reference/indexSignatures1.js index b69c891c52710..64d6764165b49 100644 --- a/tests/baselines/reference/indexSignatures1.js +++ b/tests/baselines/reference/indexSignatures1.js @@ -30,6 +30,18 @@ const x1 = combo['foo-test']; // 'a' | 'b' const x2 = combo['test-bar']; // 'b' | 'c' const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) +declare var str: string; + +const x4 = combo[`foo-${str}`]; +const x5 = combo[`${str}-bar`]; +const x6 = combo[`foo-${str}-bar`]; + +declare let combo2: { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string }; + +const x7 = combo2['axxxbyyyc']; +const x8 = combo2['ayyyxxxbc']; +const x9 = combo2['axxxbbbyc']; // Error + // Property access on template pattern index signature declare let dom: { [x: `data${string}`]: string }; @@ -76,8 +88,52 @@ type Invalid = { [key: 'a' | 'b' | 'c']: string; // Error [key: T | number]: string; // Error [key: Error]: string; // Error + [key: T & string]: string; // Error } +// Intersections in index signatures + +type Tag1 = { __tag1__: void }; +type Tag2 = { __tag2__: void }; + +type TaggedString1 = string & Tag1; +type TaggedString2 = string & Tag2; + +declare let obj1: { [key: TaggedString1]: string }; +declare let obj2: { [key: TaggedString2]: string }; +declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; +declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; + +declare let s0: string; +declare let s1: TaggedString1; +declare let s2: TaggedString2; +declare let s3: TaggedString1 | TaggedString2; +declare let s4: TaggedString1 & TaggedString2; + +obj1[s0]; // Error +obj1[s1]; +obj1[s2]; // Error +obj1[s3]; // Error +obj1[s4]; + +obj2[s0]; // Error +obj2[s1]; +obj2[s2]; +obj2[s3]; // Error +obj2[s4]; + +obj3[s0]; // Error +obj3[s1]; +obj3[s2]; +obj3[s3]; +obj3[s4]; + +obj4[s0]; // Error +obj4[s1]; // Error +obj4[s2]; // Error +obj4[s3]; // Error +obj4[s4]; + // Repros from #1863 const system = Symbol('system'); @@ -171,6 +227,12 @@ function gg2(x, y) { const x1 = combo['foo-test']; // 'a' | 'b' const x2 = combo['test-bar']; // 'b' | 'c' const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) +const x4 = combo[`foo-${str}`]; +const x5 = combo[`${str}-bar`]; +const x6 = combo[`foo-${str}-bar`]; +const x7 = combo2['axxxbyyyc']; +const x8 = combo2['ayyyxxxbc']; +const x9 = combo2['axxxbbbyc']; // Error const y1 = dom['data123']; const y2 = dom.data123; // Excess property checking for template pattern index signature @@ -180,6 +242,26 @@ const funcs = { sfoo: x => x.length, nfoo: x => x * 2, // n: number }; +obj1[s0]; // Error +obj1[s1]; +obj1[s2]; // Error +obj1[s3]; // Error +obj1[s4]; +obj2[s0]; // Error +obj2[s1]; +obj2[s2]; +obj2[s3]; // Error +obj2[s4]; +obj3[s0]; // Error +obj3[s1]; +obj3[s2]; +obj3[s3]; +obj3[s4]; +obj4[s0]; // Error +obj4[s1]; // Error +obj4[s2]; // Error +obj4[s3]; // Error +obj4[s4]; // Repros from #1863 const system = Symbol('system'); const SomeSytePlugin = Symbol('SomeSytePlugin'); @@ -251,6 +333,16 @@ declare let combo: { declare const x1: "a" | "b"; declare const x2: "b" | "c"; declare const x3: "b"; +declare var str: string; +declare const x4: "a" | "b"; +declare const x5: "b" | "c"; +declare const x6: "b"; +declare let combo2: { + [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; +}; +declare const x7: string; +declare const x8: string; +declare const x9: any; declare let dom: { [x: `data${string}`]: string; }; @@ -276,7 +368,33 @@ declare type Invalid = { [key: 'a' | 'b' | 'c']: string; [key: T | number]: string; [key: Error]: string; + [key: T & string]: string; +}; +declare type Tag1 = { + __tag1__: void; +}; +declare type Tag2 = { + __tag2__: void; +}; +declare type TaggedString1 = string & Tag1; +declare type TaggedString2 = string & Tag2; +declare let obj1: { + [key: TaggedString1]: string; +}; +declare let obj2: { + [key: TaggedString2]: string; +}; +declare let obj3: { + [key: TaggedString1 | TaggedString2]: string; +}; +declare let obj4: { + [key: TaggedString1 & TaggedString2]: string; }; +declare let s0: string; +declare let s1: TaggedString1; +declare let s2: TaggedString2; +declare let s3: TaggedString1 | TaggedString2; +declare let s4: TaggedString1 & TaggedString2; declare const system: unique symbol; declare const SomeSytePlugin: unique symbol; interface Plugs { diff --git a/tests/baselines/reference/indexSignatures1.symbols b/tests/baselines/reference/indexSignatures1.symbols index 94f485b9d264e..feddd2bdf8d59 100644 --- a/tests/baselines/reference/indexSignatures1.symbols +++ b/tests/baselines/reference/indexSignatures1.symbols @@ -87,317 +87,496 @@ const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) >x3 : Symbol(x3, Decl(indexSignatures1.ts, 29, 5)) >combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) +declare var str: string; +>str : Symbol(str, Decl(indexSignatures1.ts, 31, 11)) + +const x4 = combo[`foo-${str}`]; +>x4 : Symbol(x4, Decl(indexSignatures1.ts, 33, 5)) +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) +>str : Symbol(str, Decl(indexSignatures1.ts, 31, 11)) + +const x5 = combo[`${str}-bar`]; +>x5 : Symbol(x5, Decl(indexSignatures1.ts, 34, 5)) +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) +>str : Symbol(str, Decl(indexSignatures1.ts, 31, 11)) + +const x6 = combo[`foo-${str}-bar`]; +>x6 : Symbol(x6, Decl(indexSignatures1.ts, 35, 5)) +>combo : Symbol(combo, Decl(indexSignatures1.ts, 26, 11)) +>str : Symbol(str, Decl(indexSignatures1.ts, 31, 11)) + +declare let combo2: { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string }; +>combo2 : Symbol(combo2, Decl(indexSignatures1.ts, 37, 11)) +>x : Symbol(x, Decl(indexSignatures1.ts, 37, 23)) + +const x7 = combo2['axxxbyyyc']; +>x7 : Symbol(x7, Decl(indexSignatures1.ts, 39, 5)) +>combo2 : Symbol(combo2, Decl(indexSignatures1.ts, 37, 11)) + +const x8 = combo2['ayyyxxxbc']; +>x8 : Symbol(x8, Decl(indexSignatures1.ts, 40, 5)) +>combo2 : Symbol(combo2, Decl(indexSignatures1.ts, 37, 11)) + +const x9 = combo2['axxxbbbyc']; // Error +>x9 : Symbol(x9, Decl(indexSignatures1.ts, 41, 5)) +>combo2 : Symbol(combo2, Decl(indexSignatures1.ts, 37, 11)) + // Property access on template pattern index signature declare let dom: { [x: `data${string}`]: string }; ->dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) ->x : Symbol(x, Decl(indexSignatures1.ts, 33, 20)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 45, 11)) +>x : Symbol(x, Decl(indexSignatures1.ts, 45, 20)) const y1 = dom['data123']; ->y1 : Symbol(y1, Decl(indexSignatures1.ts, 34, 5)) ->dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) +>y1 : Symbol(y1, Decl(indexSignatures1.ts, 46, 5)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 45, 11)) const y2 = dom.data123; ->y2 : Symbol(y2, Decl(indexSignatures1.ts, 35, 5)) ->dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) +>y2 : Symbol(y2, Decl(indexSignatures1.ts, 47, 5)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 45, 11)) // Excess property checking for template pattern index signature dom = { data123: 'hello' }; ->dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) ->data123 : Symbol(data123, Decl(indexSignatures1.ts, 39, 7)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 45, 11)) +>data123 : Symbol(data123, Decl(indexSignatures1.ts, 51, 7)) dom = { date123: 'hello' }; // Error ->dom : Symbol(dom, Decl(indexSignatures1.ts, 33, 11)) ->date123 : Symbol(date123, Decl(indexSignatures1.ts, 40, 7)) +>dom : Symbol(dom, Decl(indexSignatures1.ts, 45, 11)) +>date123 : Symbol(date123, Decl(indexSignatures1.ts, 52, 7)) // Contextual typing by index signature with template literal pattern type Funcs = { ->Funcs : Symbol(Funcs, Decl(indexSignatures1.ts, 40, 27)) +>Funcs : Symbol(Funcs, Decl(indexSignatures1.ts, 52, 27)) [key: `s${string}`]: (x: string) => void, ->key : Symbol(key, Decl(indexSignatures1.ts, 45, 5)) ->x : Symbol(x, Decl(indexSignatures1.ts, 45, 26)) +>key : Symbol(key, Decl(indexSignatures1.ts, 57, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 57, 26)) [key: `n${string}`]: (x: number) => void, ->key : Symbol(key, Decl(indexSignatures1.ts, 46, 5)) ->x : Symbol(x, Decl(indexSignatures1.ts, 46, 26)) +>key : Symbol(key, Decl(indexSignatures1.ts, 58, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 58, 26)) } const funcs: Funcs = { ->funcs : Symbol(funcs, Decl(indexSignatures1.ts, 49, 5)) ->Funcs : Symbol(Funcs, Decl(indexSignatures1.ts, 40, 27)) +>funcs : Symbol(funcs, Decl(indexSignatures1.ts, 61, 5)) +>Funcs : Symbol(Funcs, Decl(indexSignatures1.ts, 52, 27)) sfoo: x => x.length, // x: string ->sfoo : Symbol(sfoo, Decl(indexSignatures1.ts, 49, 22)) ->x : Symbol(x, Decl(indexSignatures1.ts, 50, 9)) +>sfoo : Symbol(sfoo, Decl(indexSignatures1.ts, 61, 22)) +>x : Symbol(x, Decl(indexSignatures1.ts, 62, 9)) >x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) ->x : Symbol(x, Decl(indexSignatures1.ts, 50, 9)) +>x : Symbol(x, Decl(indexSignatures1.ts, 62, 9)) >length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) nfoo: x => x * 2, // n: number ->nfoo : Symbol(nfoo, Decl(indexSignatures1.ts, 50, 24)) ->x : Symbol(x, Decl(indexSignatures1.ts, 51, 9)) ->x : Symbol(x, Decl(indexSignatures1.ts, 51, 9)) +>nfoo : Symbol(nfoo, Decl(indexSignatures1.ts, 62, 24)) +>x : Symbol(x, Decl(indexSignatures1.ts, 63, 9)) +>x : Symbol(x, Decl(indexSignatures1.ts, 63, 9)) } // Duplicate index signature checking type Duplicates = { ->Duplicates : Symbol(Duplicates, Decl(indexSignatures1.ts, 52, 1)) +>Duplicates : Symbol(Duplicates, Decl(indexSignatures1.ts, 64, 1)) [key: string | number]: any; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 57, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 69, 5)) [key: number | symbol]: any; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 58, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 70, 5)) [key: symbol | `foo${string}`]: any; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 59, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 71, 5)) [key: `foo${string}`]: any; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 60, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 72, 5)) } // Conflicting index signature checking type Conflicting = { ->Conflicting : Symbol(Conflicting, Decl(indexSignatures1.ts, 61, 1)) +>Conflicting : Symbol(Conflicting, Decl(indexSignatures1.ts, 73, 1)) [key: `a${string}`]: 'a'; ->key : Symbol(key, Decl(indexSignatures1.ts, 66, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 78, 5)) [key: `${string}a`]: 'b'; ->key : Symbol(key, Decl(indexSignatures1.ts, 67, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 79, 5)) [key: `a${string}a`]: 'c'; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 68, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 80, 5)) } // Invalid index signatures type Invalid = { ->Invalid : Symbol(Invalid, Decl(indexSignatures1.ts, 69, 1)) ->T : Symbol(T, Decl(indexSignatures1.ts, 73, 13)) +>Invalid : Symbol(Invalid, Decl(indexSignatures1.ts, 81, 1)) +>T : Symbol(T, Decl(indexSignatures1.ts, 85, 13)) [key: 'a' | 'b' | 'c']: string; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 74, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 86, 5)) [key: T | number]: string; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 75, 5)) ->T : Symbol(T, Decl(indexSignatures1.ts, 73, 13)) +>key : Symbol(key, Decl(indexSignatures1.ts, 87, 5)) +>T : Symbol(T, Decl(indexSignatures1.ts, 85, 13)) [key: Error]: string; // Error ->key : Symbol(key, Decl(indexSignatures1.ts, 76, 5)) +>key : Symbol(key, Decl(indexSignatures1.ts, 88, 5)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + [key: T & string]: string; // Error +>key : Symbol(key, Decl(indexSignatures1.ts, 89, 5)) +>T : Symbol(T, Decl(indexSignatures1.ts, 85, 13)) } +// Intersections in index signatures + +type Tag1 = { __tag1__: void }; +>Tag1 : Symbol(Tag1, Decl(indexSignatures1.ts, 90, 1)) +>__tag1__ : Symbol(__tag1__, Decl(indexSignatures1.ts, 94, 13)) + +type Tag2 = { __tag2__: void }; +>Tag2 : Symbol(Tag2, Decl(indexSignatures1.ts, 94, 31)) +>__tag2__ : Symbol(__tag2__, Decl(indexSignatures1.ts, 95, 13)) + +type TaggedString1 = string & Tag1; +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>Tag1 : Symbol(Tag1, Decl(indexSignatures1.ts, 90, 1)) + +type TaggedString2 = string & Tag2; +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) +>Tag2 : Symbol(Tag2, Decl(indexSignatures1.ts, 94, 31)) + +declare let obj1: { [key: TaggedString1]: string }; +>obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 100, 21)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) + +declare let obj2: { [key: TaggedString2]: string }; +>obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 101, 21)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; +>obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 102, 21)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; +>obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 103, 21)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +declare let s0: string; +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) + +declare let s1: TaggedString1; +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) + +declare let s2: TaggedString2; +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +declare let s3: TaggedString1 | TaggedString2; +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +declare let s4: TaggedString1 & TaggedString2; +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +obj1[s0]; // Error +>obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) + +obj1[s1]; +>obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) + +obj1[s2]; // Error +>obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) + +obj1[s3]; // Error +>obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) + +obj1[s4]; +>obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) + +obj2[s0]; // Error +>obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) + +obj2[s1]; +>obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) + +obj2[s2]; +>obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) + +obj2[s3]; // Error +>obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) + +obj2[s4]; +>obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) + +obj3[s0]; // Error +>obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) + +obj3[s1]; +>obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) + +obj3[s2]; +>obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) + +obj3[s3]; +>obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) + +obj3[s4]; +>obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) + +obj4[s0]; // Error +>obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) + +obj4[s1]; // Error +>obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) + +obj4[s2]; // Error +>obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) + +obj4[s3]; // Error +>obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) + +obj4[s4]; +>obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) + // Repros from #1863 const system = Symbol('system'); ->system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) const SomeSytePlugin = Symbol('SomeSytePlugin'); ->SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 82, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 138, 5)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) interface Plugs { ->Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 82, 48)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 138, 48)) [key: symbol]: (...args: any) => unknown; ->key : Symbol(key, Decl(indexSignatures1.ts, 85, 5)) ->args : Symbol(args, Decl(indexSignatures1.ts, 85, 20)) +>key : Symbol(key, Decl(indexSignatures1.ts, 141, 5)) +>args : Symbol(args, Decl(indexSignatures1.ts, 141, 20)) } const plugins = { ->plugins : Symbol(plugins, Decl(indexSignatures1.ts, 88, 5)) +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 144, 5)) "user": {} as Plugs, ->"user" : Symbol("user", Decl(indexSignatures1.ts, 88, 17)) ->Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 82, 48)) +>"user" : Symbol("user", Decl(indexSignatures1.ts, 144, 17)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 138, 48)) [system]: {} as Plugs ->[system] : Symbol([system], Decl(indexSignatures1.ts, 89, 24)) ->system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) ->Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 82, 48)) +>[system] : Symbol([system], Decl(indexSignatures1.ts, 145, 24)) +>system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 138, 48)) }; plugins[system][SomeSytePlugin] = () => console.log('awsome'); ->plugins : Symbol(plugins, Decl(indexSignatures1.ts, 88, 5)) ->system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) ->SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 82, 5)) +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 144, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 138, 5)) >console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) >console : Symbol(console, Decl(lib.dom.d.ts, --, --)) >log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) plugins[system][SomeSytePlugin](); ->plugins : Symbol(plugins, Decl(indexSignatures1.ts, 88, 5)) ->system : Symbol(system, Decl(indexSignatures1.ts, 81, 5)) ->SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 82, 5)) +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 144, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 138, 5)) var theAnswer: symbol = Symbol('secret'); ->theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 96, 3)) +>theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 152, 3)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) var obj = {} as Record; ->obj : Symbol(obj, Decl(indexSignatures1.ts, 97, 3)) +>obj : Symbol(obj, Decl(indexSignatures1.ts, 153, 3)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) obj[theAnswer] = 42; ->obj : Symbol(obj, Decl(indexSignatures1.ts, 97, 3)) ->theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 96, 3)) +>obj : Symbol(obj, Decl(indexSignatures1.ts, 153, 3)) +>theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 152, 3)) // Repro from #26470 const directive = Symbol('directive'); ->directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; ->foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) ->TArg : Symbol(TArg, Decl(indexSignatures1.ts, 103, 21)) ->TRet : Symbol(TRet, Decl(indexSignatures1.ts, 103, 26)) ->TDir : Symbol(TDir, Decl(indexSignatures1.ts, 103, 32)) ->options : Symbol(options, Decl(indexSignatures1.ts, 103, 39)) ->x : Symbol(x, Decl(indexSignatures1.ts, 103, 51)) ->arg : Symbol(arg, Decl(indexSignatures1.ts, 103, 66)) ->TArg : Symbol(TArg, Decl(indexSignatures1.ts, 103, 21)) ->TRet : Symbol(TRet, Decl(indexSignatures1.ts, 103, 26)) ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 103, 90)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) ->TDir : Symbol(TDir, Decl(indexSignatures1.ts, 103, 32)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) +>TArg : Symbol(TArg, Decl(indexSignatures1.ts, 159, 21)) +>TRet : Symbol(TRet, Decl(indexSignatures1.ts, 159, 26)) +>TDir : Symbol(TDir, Decl(indexSignatures1.ts, 159, 32)) +>options : Symbol(options, Decl(indexSignatures1.ts, 159, 39)) +>x : Symbol(x, Decl(indexSignatures1.ts, 159, 51)) +>arg : Symbol(arg, Decl(indexSignatures1.ts, 159, 66)) +>TArg : Symbol(TArg, Decl(indexSignatures1.ts, 159, 21)) +>TRet : Symbol(TRet, Decl(indexSignatures1.ts, 159, 26)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 159, 90)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) +>TDir : Symbol(TDir, Decl(indexSignatures1.ts, 159, 32)) let case1 = foo({ ->case1 : Symbol(case1, Decl(indexSignatures1.ts, 105, 3)) ->foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) +>case1 : Symbol(case1, Decl(indexSignatures1.ts, 161, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) [directive]: (x: string) => 'str', ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 105, 17)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) ->x : Symbol(x, Decl(indexSignatures1.ts, 106, 18)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 161, 17)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 162, 18)) addOne: (x: number) => x + 1, ->addOne : Symbol(addOne, Decl(indexSignatures1.ts, 106, 38)) ->x : Symbol(x, Decl(indexSignatures1.ts, 107, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 107, 13)) +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 162, 38)) +>x : Symbol(x, Decl(indexSignatures1.ts, 163, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 163, 13)) double: (x: number) => x + x, ->double : Symbol(double, Decl(indexSignatures1.ts, 107, 33)) ->x : Symbol(x, Decl(indexSignatures1.ts, 108, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 108, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 108, 13)) +>double : Symbol(double, Decl(indexSignatures1.ts, 163, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 164, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 164, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 164, 13)) }); let case2 = foo({ ->case2 : Symbol(case2, Decl(indexSignatures1.ts, 111, 3)) ->foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) +>case2 : Symbol(case2, Decl(indexSignatures1.ts, 167, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) addOne: (x: number) => x + 1, ->addOne : Symbol(addOne, Decl(indexSignatures1.ts, 111, 17)) ->x : Symbol(x, Decl(indexSignatures1.ts, 112, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 112, 13)) +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 167, 17)) +>x : Symbol(x, Decl(indexSignatures1.ts, 168, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 168, 13)) double: (x: number) => x + x, ->double : Symbol(double, Decl(indexSignatures1.ts, 112, 33)) ->x : Symbol(x, Decl(indexSignatures1.ts, 113, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 113, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 113, 13)) +>double : Symbol(double, Decl(indexSignatures1.ts, 168, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 169, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 169, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 169, 13)) [directive]: (x: string) => 'str', ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 113, 33)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) ->x : Symbol(x, Decl(indexSignatures1.ts, 114, 18)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 169, 33)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 170, 18)) }); let case3 = foo({ ->case3 : Symbol(case3, Decl(indexSignatures1.ts, 117, 3)) ->foo : Symbol(foo, Decl(indexSignatures1.ts, 102, 38)) +>case3 : Symbol(case3, Decl(indexSignatures1.ts, 173, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) [directive]: 'str', ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 117, 17)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 102, 5)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 173, 17)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) addOne: (x: number) => x + 1, ->addOne : Symbol(addOne, Decl(indexSignatures1.ts, 118, 23)) ->x : Symbol(x, Decl(indexSignatures1.ts, 119, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 119, 13)) +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 174, 23)) +>x : Symbol(x, Decl(indexSignatures1.ts, 175, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 175, 13)) double: (x: number) => x + x, ->double : Symbol(double, Decl(indexSignatures1.ts, 119, 33)) ->x : Symbol(x, Decl(indexSignatures1.ts, 120, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 120, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 120, 13)) +>double : Symbol(double, Decl(indexSignatures1.ts, 175, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 176, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 176, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 176, 13)) }); // Repros from #42192 type Pseudo = `&:${string}`; ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) const AmIPseudo1: Pseudo = '&:test'; ->AmIPseudo1 : Symbol(AmIPseudo1, Decl(indexSignatures1.ts, 127, 5)) ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) +>AmIPseudo1 : Symbol(AmIPseudo1, Decl(indexSignatures1.ts, 183, 5)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) const AmIPseudo: Pseudo = '&'; // Error ->AmIPseudo : Symbol(AmIPseudo, Decl(indexSignatures1.ts, 128, 5)) ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) +>AmIPseudo : Symbol(AmIPseudo, Decl(indexSignatures1.ts, 184, 5)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) type PseudoDeclaration = { [key in Pseudo]: string }; ->PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 128, 30)) ->key : Symbol(key, Decl(indexSignatures1.ts, 130, 28)) ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 121, 3)) +>PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 184, 30)) +>key : Symbol(key, Decl(indexSignatures1.ts, 186, 28)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error ->test : Symbol(test, Decl(indexSignatures1.ts, 132, 5)) ->PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 128, 30)) ->'someKey' : Symbol('someKey', Decl(indexSignatures1.ts, 132, 33)) +>test : Symbol(test, Decl(indexSignatures1.ts, 188, 5)) +>PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 184, 30)) +>'someKey' : Symbol('someKey', Decl(indexSignatures1.ts, 188, 33)) type FieldPattern = `/${string}`; ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) const path1: FieldPattern = '/one'; ->path1 : Symbol(path1, Decl(indexSignatures1.ts, 136, 5)) ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) +>path1 : Symbol(path1, Decl(indexSignatures1.ts, 192, 5)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) const path2: FieldPattern = 'two'; // Error ->path2 : Symbol(path2, Decl(indexSignatures1.ts, 137, 5)) ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) +>path2 : Symbol(path2, Decl(indexSignatures1.ts, 193, 5)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) type PathsObject = { [P in FieldPattern]: object; }; ->PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 137, 34)) ->P : Symbol(P, Decl(indexSignatures1.ts, 139, 22)) ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 132, 60)) +>PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 193, 34)) +>P : Symbol(P, Decl(indexSignatures1.ts, 195, 22)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) const pathObject: PathsObject = 123; // Error ->pathObject : Symbol(pathObject, Decl(indexSignatures1.ts, 140, 5)) ->PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 137, 34)) +>pathObject : Symbol(pathObject, Decl(indexSignatures1.ts, 196, 5)) +>PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 193, 34)) type IdType = `${number}-${number}-${number}-${number}` ->IdType : Symbol(IdType, Decl(indexSignatures1.ts, 140, 36)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 196, 36)) const id: IdType = '0000-0000-0000-0001'; ->id : Symbol(id, Decl(indexSignatures1.ts, 143, 5)) ->IdType : Symbol(IdType, Decl(indexSignatures1.ts, 140, 36)) +>id : Symbol(id, Decl(indexSignatures1.ts, 199, 5)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 196, 36)) type A = Record; ->A : Symbol(A, Decl(indexSignatures1.ts, 143, 41)) +>A : Symbol(A, Decl(indexSignatures1.ts, 199, 41)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->IdType : Symbol(IdType, Decl(indexSignatures1.ts, 140, 36)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 196, 36)) const a: A = { [id]: 'test' } ->a : Symbol(a, Decl(indexSignatures1.ts, 147, 5)) ->A : Symbol(A, Decl(indexSignatures1.ts, 143, 41)) ->[id] : Symbol([id], Decl(indexSignatures1.ts, 147, 14)) ->id : Symbol(id, Decl(indexSignatures1.ts, 143, 5)) +>a : Symbol(a, Decl(indexSignatures1.ts, 203, 5)) +>A : Symbol(A, Decl(indexSignatures1.ts, 199, 41)) +>[id] : Symbol([id], Decl(indexSignatures1.ts, 203, 14)) +>id : Symbol(id, Decl(indexSignatures1.ts, 199, 5)) let aid = a[id]; ->aid : Symbol(aid, Decl(indexSignatures1.ts, 149, 3)) ->a : Symbol(a, Decl(indexSignatures1.ts, 147, 5)) ->id : Symbol(id, Decl(indexSignatures1.ts, 143, 5)) +>aid : Symbol(aid, Decl(indexSignatures1.ts, 205, 3)) +>a : Symbol(a, Decl(indexSignatures1.ts, 203, 5)) +>id : Symbol(id, Decl(indexSignatures1.ts, 199, 5)) diff --git a/tests/baselines/reference/indexSignatures1.types b/tests/baselines/reference/indexSignatures1.types index 63828051618c0..e802b7fc7eecf 100644 --- a/tests/baselines/reference/indexSignatures1.types +++ b/tests/baselines/reference/indexSignatures1.types @@ -96,6 +96,52 @@ const x3 = combo['foo-test-bar']; // 'b' (('a' | 'b') & ('b' | 'c')) >combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } >'foo-test-bar' : "foo-test-bar" +declare var str: string; +>str : string + +const x4 = combo[`foo-${str}`]; +>x4 : "a" | "b" +>combo[`foo-${str}`] : "a" | "b" +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>`foo-${str}` : `foo-${string}` +>str : string + +const x5 = combo[`${str}-bar`]; +>x5 : "b" | "c" +>combo[`${str}-bar`] : "b" | "c" +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>`${str}-bar` : `${string}-bar` +>str : string + +const x6 = combo[`foo-${str}-bar`]; +>x6 : "b" +>combo[`foo-${str}-bar`] : "b" +>combo : { [x: `foo-${string}`]: "a" | "b"; } & { [x: `${string}-bar`]: "b" | "c"; } +>`foo-${str}-bar` : `foo-${string}-bar` +>str : string + +declare let combo2: { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string }; +>combo2 : { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; } +>x : `${string}xxx${string}` & `${string}yyy${string}` + +const x7 = combo2['axxxbyyyc']; +>x7 : string +>combo2['axxxbyyyc'] : string +>combo2 : { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; } +>'axxxbyyyc' : "axxxbyyyc" + +const x8 = combo2['ayyyxxxbc']; +>x8 : string +>combo2['ayyyxxxbc'] : string +>combo2 : { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; } +>'ayyyxxxbc' : "ayyyxxxbc" + +const x9 = combo2['axxxbbbyc']; // Error +>x9 : any +>combo2['axxxbbbyc'] : any +>combo2 : { [x: `${string}xxx${string}` & `${string}yyy${string}`]: string; } +>'axxxbbbyc' : "axxxbbbyc" + // Property access on template pattern index signature declare let dom: { [x: `data${string}`]: string }; @@ -211,8 +257,158 @@ type Invalid = { [key: Error]: string; // Error >key : Error + + [key: T & string]: string; // Error +>key : T & string } +// Intersections in index signatures + +type Tag1 = { __tag1__: void }; +>Tag1 : Tag1 +>__tag1__ : void + +type Tag2 = { __tag2__: void }; +>Tag2 : Tag2 +>__tag2__ : void + +type TaggedString1 = string & Tag1; +>TaggedString1 : TaggedString1 + +type TaggedString2 = string & Tag2; +>TaggedString2 : TaggedString2 + +declare let obj1: { [key: TaggedString1]: string }; +>obj1 : { [key: TaggedString1]: string; } +>key : TaggedString1 + +declare let obj2: { [key: TaggedString2]: string }; +>obj2 : { [key: TaggedString2]: string; } +>key : TaggedString2 + +declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; +>obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>key : TaggedString1 | TaggedString2 + +declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; +>obj4 : { [key: string & Tag1 & Tag2]: string; } +>key : string & Tag1 & Tag2 + +declare let s0: string; +>s0 : string + +declare let s1: TaggedString1; +>s1 : TaggedString1 + +declare let s2: TaggedString2; +>s2 : TaggedString2 + +declare let s3: TaggedString1 | TaggedString2; +>s3 : TaggedString1 | TaggedString2 + +declare let s4: TaggedString1 & TaggedString2; +>s4 : string & Tag1 & Tag2 + +obj1[s0]; // Error +>obj1[s0] : any +>obj1 : { [key: TaggedString1]: string; } +>s0 : string + +obj1[s1]; +>obj1[s1] : string +>obj1 : { [key: TaggedString1]: string; } +>s1 : TaggedString1 + +obj1[s2]; // Error +>obj1[s2] : any +>obj1 : { [key: TaggedString1]: string; } +>s2 : TaggedString2 + +obj1[s3]; // Error +>obj1[s3] : any +>obj1 : { [key: TaggedString1]: string; } +>s3 : TaggedString1 | TaggedString2 + +obj1[s4]; +>obj1[s4] : string +>obj1 : { [key: TaggedString1]: string; } +>s4 : string & Tag1 & Tag2 + +obj2[s0]; // Error +>obj2[s0] : any +>obj2 : { [key: TaggedString2]: string; } +>s0 : string + +obj2[s1]; +>obj2[s1] : any +>obj2 : { [key: TaggedString2]: string; } +>s1 : TaggedString1 + +obj2[s2]; +>obj2[s2] : string +>obj2 : { [key: TaggedString2]: string; } +>s2 : TaggedString2 + +obj2[s3]; // Error +>obj2[s3] : any +>obj2 : { [key: TaggedString2]: string; } +>s3 : TaggedString1 | TaggedString2 + +obj2[s4]; +>obj2[s4] : string +>obj2 : { [key: TaggedString2]: string; } +>s4 : string & Tag1 & Tag2 + +obj3[s0]; // Error +>obj3[s0] : any +>obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>s0 : string + +obj3[s1]; +>obj3[s1] : string +>obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>s1 : TaggedString1 + +obj3[s2]; +>obj3[s2] : string +>obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>s2 : TaggedString2 + +obj3[s3]; +>obj3[s3] : string +>obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>s3 : TaggedString1 | TaggedString2 + +obj3[s4]; +>obj3[s4] : string +>obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>s4 : string & Tag1 & Tag2 + +obj4[s0]; // Error +>obj4[s0] : any +>obj4 : { [key: string & Tag1 & Tag2]: string; } +>s0 : string + +obj4[s1]; // Error +>obj4[s1] : any +>obj4 : { [key: string & Tag1 & Tag2]: string; } +>s1 : TaggedString1 + +obj4[s2]; // Error +>obj4[s2] : any +>obj4 : { [key: string & Tag1 & Tag2]: string; } +>s2 : TaggedString2 + +obj4[s3]; // Error +>obj4[s3] : any +>obj4 : { [key: string & Tag1 & Tag2]: string; } +>s3 : TaggedString1 | TaggedString2 + +obj4[s4]; +>obj4[s4] : string +>obj4 : { [key: string & Tag1 & Tag2]: string; } +>s4 : string & Tag1 & Tag2 + // Repros from #1863 const system = Symbol('system'); From bf633d8861e6e638d8437d5fa61dc88585158f25 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jun 2021 16:01:41 -0700 Subject: [PATCH 50/56] Symbol index signatures from object literals with computed symbol properties --- src/compiler/checker.ts | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a5b395d07fb92..1d95b498763c6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26134,10 +26134,19 @@ namespace ts { return isNumericLiteralName(symbol.escapedName) || (firstDecl && isNamedDeclaration(firstDecl) && isNumericName(firstDecl.name)); } + function isSymbolWithSymbolName(symbol: Symbol) { + const firstDecl = symbol.declarations?.[0]; + return isKnownSymbol(symbol) || (firstDecl && isNamedDeclaration(firstDecl) && isComputedPropertyName(firstDecl.name) && + isTypeAssignableToKind(checkComputedPropertyName(firstDecl.name), TypeFlags.ESSymbol)); + } + function getObjectLiteralIndexInfo(node: ObjectLiteralExpression, offset: number, properties: Symbol[], keyType: Type): IndexInfo { const propTypes: Type[] = []; for (let i = offset; i < properties.length; i++) { - if (keyType === stringType || isSymbolWithNumericName(properties[i])) { + const prop = properties[i]; + if (keyType === stringType && !isSymbolWithSymbolName(prop) || + keyType === numberType && isSymbolWithNumericName(prop) || + keyType === esSymbolType && isSymbolWithSymbolName(prop)) { propTypes.push(getTypeOfSymbol(properties[i])); } } @@ -26179,6 +26188,7 @@ namespace ts { let patternWithComputedProperties = false; let hasComputedStringProperty = false; let hasComputedNumberProperty = false; + let hasComputedSymbolProperty = false; // Spreads may cause an early bail; ensure computed names are always checked (this is cached) // As otherwise they may not be checked until exports for the type at this position are retrieved, @@ -26267,6 +26277,7 @@ namespace ts { propertiesTable = createSymbolTable(); hasComputedStringProperty = false; hasComputedNumberProperty = false; + hasComputedSymbolProperty = false; } const type = getReducedType(checkExpression(memberDecl.expression)); if (isValidSpreadType(type)) { @@ -26300,6 +26311,9 @@ namespace ts { if (isTypeAssignableTo(computedNameType, numberType)) { hasComputedNumberProperty = true; } + else if (isTypeAssignableTo(computedNameType, esSymbolType)) { + hasComputedSymbolProperty = true; + } else { hasComputedStringProperty = true; } @@ -26350,9 +26364,10 @@ namespace ts { return createObjectLiteralType(); function createObjectLiteralType() { - const stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType) : undefined; - const numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType) : undefined; - const indexInfos = stringIndexInfo ? numberIndexInfo ? [stringIndexInfo, numberIndexInfo] : [stringIndexInfo] : numberIndexInfo ? [numberIndexInfo] : emptyArray; + const indexInfos = []; + if (hasComputedStringProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, stringType)); + if (hasComputedNumberProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, numberType)); + if (hasComputedSymbolProperty) indexInfos.push(getObjectLiteralIndexInfo(node, offset, propertiesArray, esSymbolType)); const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, indexInfos); result.objectFlags |= objectFlags | ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral; if (isJSObjectLiteral) { From 5baae83fc3e7ea591deaa0a7e514307ceeb9fb58 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jun 2021 16:01:58 -0700 Subject: [PATCH 51/56] Accept new baselines --- tests/baselines/reference/symbolProperty1.types | 4 ++-- tests/baselines/reference/symbolProperty2.types | 4 ++-- tests/baselines/reference/symbolProperty4.types | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/symbolProperty1.types b/tests/baselines/reference/symbolProperty1.types index 8ee046b05da51..b3e293f05ada2 100644 --- a/tests/baselines/reference/symbolProperty1.types +++ b/tests/baselines/reference/symbolProperty1.types @@ -3,8 +3,8 @@ var s: symbol; >s : symbol var x = { ->x : { [x: string]: number | (() => void); } ->{ [s]: 0, [s]() { }, get [s]() { return 0; }} : { [x: string]: number | (() => void); } +>x : { [x: symbol]: number | (() => void); } +>{ [s]: 0, [s]() { }, get [s]() { return 0; }} : { [x: symbol]: number | (() => void); } [s]: 0, >[s] : number diff --git a/tests/baselines/reference/symbolProperty2.types b/tests/baselines/reference/symbolProperty2.types index 5b095c47a72d1..d534da000bdc2 100644 --- a/tests/baselines/reference/symbolProperty2.types +++ b/tests/baselines/reference/symbolProperty2.types @@ -5,8 +5,8 @@ var s = Symbol(); >Symbol : SymbolConstructor var x = { ->x : { [x: string]: number | (() => void); } ->{ [s]: 0, [s]() { }, get [s]() { return 0; }} : { [x: string]: number | (() => void); } +>x : { [x: symbol]: number | (() => void); } +>{ [s]: 0, [s]() { }, get [s]() { return 0; }} : { [x: symbol]: number | (() => void); } [s]: 0, >[s] : number diff --git a/tests/baselines/reference/symbolProperty4.types b/tests/baselines/reference/symbolProperty4.types index 77f4f105e79b1..c32b42679f763 100644 --- a/tests/baselines/reference/symbolProperty4.types +++ b/tests/baselines/reference/symbolProperty4.types @@ -1,7 +1,7 @@ === tests/cases/conformance/es6/Symbols/symbolProperty4.ts === var x = { ->x : { [x: string]: number | (() => void); } ->{ [Symbol()]: 0, [Symbol()]() { }, get [Symbol()]() { return 0; }} : { [x: string]: number | (() => void); } +>x : { [x: symbol]: number | (() => void); } +>{ [Symbol()]: 0, [Symbol()]() { }, get [Symbol()]() { return 0; }} : { [x: symbol]: number | (() => void); } [Symbol()]: 0, >[Symbol()] : number From 2f4c9672e93f7d72387a7fa0d2c0c7e2f74bd3f9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jun 2021 16:04:48 -0700 Subject: [PATCH 52/56] Add more tests --- .../types/members/indexSignatures1.ts | 148 ++++++++++++++---- 1 file changed, 120 insertions(+), 28 deletions(-) diff --git a/tests/cases/conformance/types/members/indexSignatures1.ts b/tests/cases/conformance/types/members/indexSignatures1.ts index e2b41df793c1e..a35471bdbfdd0 100644 --- a/tests/cases/conformance/types/members/indexSignatures1.ts +++ b/tests/cases/conformance/types/members/indexSignatures1.ts @@ -102,40 +102,132 @@ type Tag2 = { __tag2__: void }; type TaggedString1 = string & Tag1; type TaggedString2 = string & Tag2; -declare let obj1: { [key: TaggedString1]: string }; -declare let obj2: { [key: TaggedString2]: string }; -declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; -declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; - declare let s0: string; declare let s1: TaggedString1; declare let s2: TaggedString2; declare let s3: TaggedString1 | TaggedString2; declare let s4: TaggedString1 & TaggedString2; -obj1[s0]; // Error -obj1[s1]; -obj1[s2]; // Error -obj1[s3]; // Error -obj1[s4]; - -obj2[s0]; // Error -obj2[s1]; -obj2[s2]; -obj2[s3]; // Error -obj2[s4]; - -obj3[s0]; // Error -obj3[s1]; -obj3[s2]; -obj3[s3]; -obj3[s4]; - -obj4[s0]; // Error -obj4[s1]; // Error -obj4[s2]; // Error -obj4[s3]; // Error -obj4[s4]; +interface I1 { [key: TaggedString1]: string } +interface I2 { [key: TaggedString2]: string } +interface I3 { [key: TaggedString1 | TaggedString2]: string } +interface I4 { [key: TaggedString1 & TaggedString2]: string } + +declare let i1: I1; +declare let i2: I2; +declare let i3: I3; +declare let i4: I4; + +i1[s0]; // Error +i1[s1]; +i1[s2]; // Error +i1[s3]; // Error +i1[s4]; + +i2[s0]; // Error +i2[s1]; // Error +i2[s2]; +i2[s3]; // Error +i2[s4]; + +i3[s0]; // Error +i3[s1]; +i3[s2]; +i3[s3]; +i3[s4]; + +i4[s0]; // Error +i4[s1]; // Error +i4[s2]; // Error +i4[s3]; // Error +i4[s4]; + +i1 = i2; // Error +i1 = i3; +i1 = i4; // Error + +i2 = i1; // Error +i2 = i3; +i2 = i4; // Error + +i3 = i1; // Error +i3 = i2; // Error +i3 = i4; // Error + +i4 = i1; +i4 = i2; +i4 = i3; + +declare let o1: { [key: TaggedString1]: string }; +declare let o2: { [key: TaggedString2]: string }; +declare let o3: { [key: TaggedString1 | TaggedString2]: string }; +declare let o4: { [key: TaggedString1 & TaggedString2]: string }; + +o1[s0]; // Error +o1[s1]; +o1[s2]; // Error +o1[s3]; // Error +o1[s4]; + +o2[s0]; // Error +o2[s1]; // Error +o2[s2]; +o2[s3]; // Error +o2[s4]; + +o3[s0]; // Error +o3[s1]; +o3[s2]; +o3[s3]; +o3[s4]; + +o4[s0]; // Error +o4[s1]; // Error +o4[s2]; // Error +o4[s3]; // Error +o4[s4]; + +o1 = o2; +o1 = o3; +o1 = o4; + +o2 = o1; +o2 = o3; +o2 = o4; + +o3 = o1; +o3 = o2; +o3 = o4; + +o4 = o1; +o4 = o2; +o4 = o3; + +// Index signatures inferred from computed property names + +const obj10 = { + ['x']: 0 as const, + ['a' + 'b']: 1 as const, +}; + +const obj11 = { + [1]: 2 as const, + [1 + 2]: 3 as const, +}; + +const obj12 = { + [sym]: 4 as const, + [Symbol()]: 5 as const, +}; + +const obj13 = { + ['x']: 0 as const, + ['a' + 'b']: 1 as const, + [1]: 2 as const, + [1 + 2]: 3 as const, + [sym]: 4 as const, + [Symbol()]: 5 as const, +}; // Repros from #1863 From f3897c1b4ead828263305ac74cbd6e46812e2009 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 18 Jun 2021 16:04:57 -0700 Subject: [PATCH 53/56] Accept new baselines --- .../reference/indexSignatures1.errors.txt | 272 ++++++-- tests/baselines/reference/indexSignatures1.js | 307 +++++++-- .../reference/indexSignatures1.symbols | 648 +++++++++++++----- .../reference/indexSignatures1.types | 498 ++++++++++++-- 4 files changed, 1359 insertions(+), 366 deletions(-) diff --git a/tests/baselines/reference/indexSignatures1.errors.txt b/tests/baselines/reference/indexSignatures1.errors.txt index 1777166005b46..4d0310333c1d9 100644 --- a/tests/baselines/reference/indexSignatures1.errors.txt +++ b/tests/baselines/reference/indexSignatures1.errors.txt @@ -19,29 +19,58 @@ tests/cases/conformance/types/members/indexSignatures1.ts(87,6): error TS1337: A tests/cases/conformance/types/members/indexSignatures1.ts(88,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. tests/cases/conformance/types/members/indexSignatures1.ts(89,6): error TS1268: An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type. tests/cases/conformance/types/members/indexSignatures1.ts(90,6): error TS1337: An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead. -tests/cases/conformance/types/members/indexSignatures1.ts(112,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(117,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I1'. + No index signature with a parameter of type 'string' was found on type 'I1'. +tests/cases/conformance/types/members/indexSignatures1.ts(119,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type 'I1'. +tests/cases/conformance/types/members/indexSignatures1.ts(120,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type 'I1'. +tests/cases/conformance/types/members/indexSignatures1.ts(123,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I2'. + No index signature with a parameter of type 'string' was found on type 'I2'. +tests/cases/conformance/types/members/indexSignatures1.ts(124,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type 'I2'. +tests/cases/conformance/types/members/indexSignatures1.ts(126,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type 'I2'. +tests/cases/conformance/types/members/indexSignatures1.ts(129,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I3'. + No index signature with a parameter of type 'string' was found on type 'I3'. +tests/cases/conformance/types/members/indexSignatures1.ts(135,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I4'. + No index signature with a parameter of type 'string' was found on type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(136,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(137,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(138,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(141,1): error TS2322: Type 'I2' is not assignable to type 'I1'. + Index signature for type 'TaggedString1' is missing in type 'I2'. +tests/cases/conformance/types/members/indexSignatures1.ts(143,1): error TS2322: Type 'I4' is not assignable to type 'I1'. + Index signature for type 'TaggedString1' is missing in type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(145,1): error TS2322: Type 'I1' is not assignable to type 'I2'. + Index signature for type 'TaggedString2' is missing in type 'I1'. +tests/cases/conformance/types/members/indexSignatures1.ts(147,1): error TS2322: Type 'I4' is not assignable to type 'I2'. + Index signature for type 'TaggedString2' is missing in type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(149,1): error TS2322: Type 'I1' is not assignable to type 'I3'. + Index signature for type 'TaggedString2' is missing in type 'I1'. +tests/cases/conformance/types/members/indexSignatures1.ts(150,1): error TS2322: Type 'I2' is not assignable to type 'I3'. + Index signature for type 'TaggedString1' is missing in type 'I2'. +tests/cases/conformance/types/members/indexSignatures1.ts(151,1): error TS2322: Type 'I4' is not assignable to type 'I3'. + Index signature for type 'TaggedString1' is missing in type 'I4'. +tests/cases/conformance/types/members/indexSignatures1.ts(162,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; }'. No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(114,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(115,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(118,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(164,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(165,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(168,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString2]: string; }'. No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(119,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: TaggedString2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(121,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(124,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(169,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(171,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(174,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(130,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(180,1): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. No index signature with a parameter of type 'string' was found on type '{ [key: string & Tag1 & Tag2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(131,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(132,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(133,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. -tests/cases/conformance/types/members/indexSignatures1.ts(185,7): error TS2322: Type '"&"' is not assignable to type '`&:${string}`'. -tests/cases/conformance/types/members/indexSignatures1.ts(189,35): error TS2322: Type '{ someKey: string; }' is not assignable to type 'PseudoDeclaration'. +tests/cases/conformance/types/members/indexSignatures1.ts(181,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(182,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(183,1): error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. +tests/cases/conformance/types/members/indexSignatures1.ts(277,7): error TS2322: Type '"&"' is not assignable to type '`&:${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(281,35): error TS2322: Type '{ someKey: string; }' is not assignable to type 'PseudoDeclaration'. Object literal may only specify known properties, and ''someKey'' does not exist in type 'PseudoDeclaration'. -tests/cases/conformance/types/members/indexSignatures1.ts(194,7): error TS2322: Type '"two"' is not assignable to type '`/${string}`'. -tests/cases/conformance/types/members/indexSignatures1.ts(197,7): error TS2322: Type 'number' is not assignable to type 'PathsObject'. +tests/cases/conformance/types/members/indexSignatures1.ts(286,7): error TS2322: Type '"two"' is not assignable to type '`/${string}`'. +tests/cases/conformance/types/members/indexSignatures1.ts(289,7): error TS2322: Type 'number' is not assignable to type 'PathsObject'. -==== tests/cases/conformance/types/members/indexSignatures1.ts (31 errors) ==== +==== tests/cases/conformance/types/members/indexSignatures1.ts (49 errors) ==== // Symbol index signature checking const sym = Symbol(); @@ -179,66 +208,205 @@ tests/cases/conformance/types/members/indexSignatures1.ts(197,7): error TS2322: type TaggedString1 = string & Tag1; type TaggedString2 = string & Tag2; - declare let obj1: { [key: TaggedString1]: string }; - declare let obj2: { [key: TaggedString2]: string }; - declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; - declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; - declare let s0: string; declare let s1: TaggedString1; declare let s2: TaggedString2; declare let s3: TaggedString1 | TaggedString2; declare let s4: TaggedString1 & TaggedString2; - obj1[s0]; // Error - ~~~~~~~~ + interface I1 { [key: TaggedString1]: string } + interface I2 { [key: TaggedString2]: string } + interface I3 { [key: TaggedString1 | TaggedString2]: string } + interface I4 { [key: TaggedString1 & TaggedString2]: string } + + declare let i1: I1; + declare let i2: I2; + declare let i3: I3; + declare let i4: I4; + + i1[s0]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I1'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'I1'. + i1[s1]; + i1[s2]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type 'I1'. + i1[s3]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type 'I1'. + i1[s4]; + + i2[s0]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I2'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'I2'. + i2[s1]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type 'I2'. + i2[s2]; + i2[s3]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type 'I2'. + i2[s4]; + + i3[s0]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I3'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'I3'. + i3[s1]; + i3[s2]; + i3[s3]; + i3[s4]; + + i4[s0]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'I4'. +!!! error TS7053: No index signature with a parameter of type 'string' was found on type 'I4'. + i4[s1]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type 'I4'. + i4[s2]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type 'I4'. + i4[s3]; // Error + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type 'I4'. + i4[s4]; + + i1 = i2; // Error + ~~ +!!! error TS2322: Type 'I2' is not assignable to type 'I1'. +!!! error TS2322: Index signature for type 'TaggedString1' is missing in type 'I2'. + i1 = i3; + i1 = i4; // Error + ~~ +!!! error TS2322: Type 'I4' is not assignable to type 'I1'. +!!! error TS2322: Index signature for type 'TaggedString1' is missing in type 'I4'. + + i2 = i1; // Error + ~~ +!!! error TS2322: Type 'I1' is not assignable to type 'I2'. +!!! error TS2322: Index signature for type 'TaggedString2' is missing in type 'I1'. + i2 = i3; + i2 = i4; // Error + ~~ +!!! error TS2322: Type 'I4' is not assignable to type 'I2'. +!!! error TS2322: Index signature for type 'TaggedString2' is missing in type 'I4'. + + i3 = i1; // Error + ~~ +!!! error TS2322: Type 'I1' is not assignable to type 'I3'. +!!! error TS2322: Index signature for type 'TaggedString2' is missing in type 'I1'. + i3 = i2; // Error + ~~ +!!! error TS2322: Type 'I2' is not assignable to type 'I3'. +!!! error TS2322: Index signature for type 'TaggedString1' is missing in type 'I2'. + i3 = i4; // Error + ~~ +!!! error TS2322: Type 'I4' is not assignable to type 'I3'. +!!! error TS2322: Index signature for type 'TaggedString1' is missing in type 'I4'. + + i4 = i1; + i4 = i2; + i4 = i3; + + declare let o1: { [key: TaggedString1]: string }; + declare let o2: { [key: TaggedString2]: string }; + declare let o3: { [key: TaggedString1 | TaggedString2]: string }; + declare let o4: { [key: TaggedString1 & TaggedString2]: string }; + + o1[s0]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; }'. !!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; }'. - obj1[s1]; - obj1[s2]; // Error - ~~~~~~~~ + o1[s1]; + o1[s2]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. - obj1[s3]; // Error - ~~~~~~~~ + o1[s3]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString1]: string; }'. - obj1[s4]; + o1[s4]; - obj2[s0]; // Error - ~~~~~~~~ + o2[s0]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString2]: string; }'. !!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString2]: string; }'. - obj2[s1]; - ~~~~~~~~ + o2[s1]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: TaggedString2]: string; }'. - obj2[s2]; - obj2[s3]; // Error - ~~~~~~~~ + o2[s2]; + o2[s3]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: TaggedString2]: string; }'. - obj2[s4]; + o2[s4]; - obj3[s0]; // Error - ~~~~~~~~ + o3[s0]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. !!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: TaggedString1]: string; [key: TaggedString2]: string; }'. - obj3[s1]; - obj3[s2]; - obj3[s3]; - obj3[s4]; + o3[s1]; + o3[s2]; + o3[s3]; + o3[s4]; - obj4[s0]; // Error - ~~~~~~~~ + o4[s0]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. !!! error TS7053: No index signature with a parameter of type 'string' was found on type '{ [key: string & Tag1 & Tag2]: string; }'. - obj4[s1]; // Error - ~~~~~~~~ + o4[s1]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. - obj4[s2]; // Error - ~~~~~~~~ + o4[s2]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. - obj4[s3]; // Error - ~~~~~~~~ + o4[s3]; // Error + ~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'TaggedString1 | TaggedString2' can't be used to index type '{ [key: string & Tag1 & Tag2]: string; }'. - obj4[s4]; + o4[s4]; + + o1 = o2; + o1 = o3; + o1 = o4; + + o2 = o1; + o2 = o3; + o2 = o4; + + o3 = o1; + o3 = o2; + o3 = o4; + + o4 = o1; + o4 = o2; + o4 = o3; + + // Index signatures inferred from computed property names + + const obj10 = { + ['x']: 0 as const, + ['a' + 'b']: 1 as const, + }; + + const obj11 = { + [1]: 2 as const, + [1 + 2]: 3 as const, + }; + + const obj12 = { + [sym]: 4 as const, + [Symbol()]: 5 as const, + }; + + const obj13 = { + ['x']: 0 as const, + ['a' + 'b']: 1 as const, + [1]: 2 as const, + [1 + 2]: 3 as const, + [sym]: 4 as const, + [Symbol()]: 5 as const, + }; // Repros from #1863 diff --git a/tests/baselines/reference/indexSignatures1.js b/tests/baselines/reference/indexSignatures1.js index 64d6764165b49..1eb625374e65d 100644 --- a/tests/baselines/reference/indexSignatures1.js +++ b/tests/baselines/reference/indexSignatures1.js @@ -99,40 +99,132 @@ type Tag2 = { __tag2__: void }; type TaggedString1 = string & Tag1; type TaggedString2 = string & Tag2; -declare let obj1: { [key: TaggedString1]: string }; -declare let obj2: { [key: TaggedString2]: string }; -declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; -declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; - declare let s0: string; declare let s1: TaggedString1; declare let s2: TaggedString2; declare let s3: TaggedString1 | TaggedString2; declare let s4: TaggedString1 & TaggedString2; -obj1[s0]; // Error -obj1[s1]; -obj1[s2]; // Error -obj1[s3]; // Error -obj1[s4]; - -obj2[s0]; // Error -obj2[s1]; -obj2[s2]; -obj2[s3]; // Error -obj2[s4]; - -obj3[s0]; // Error -obj3[s1]; -obj3[s2]; -obj3[s3]; -obj3[s4]; - -obj4[s0]; // Error -obj4[s1]; // Error -obj4[s2]; // Error -obj4[s3]; // Error -obj4[s4]; +interface I1 { [key: TaggedString1]: string } +interface I2 { [key: TaggedString2]: string } +interface I3 { [key: TaggedString1 | TaggedString2]: string } +interface I4 { [key: TaggedString1 & TaggedString2]: string } + +declare let i1: I1; +declare let i2: I2; +declare let i3: I3; +declare let i4: I4; + +i1[s0]; // Error +i1[s1]; +i1[s2]; // Error +i1[s3]; // Error +i1[s4]; + +i2[s0]; // Error +i2[s1]; // Error +i2[s2]; +i2[s3]; // Error +i2[s4]; + +i3[s0]; // Error +i3[s1]; +i3[s2]; +i3[s3]; +i3[s4]; + +i4[s0]; // Error +i4[s1]; // Error +i4[s2]; // Error +i4[s3]; // Error +i4[s4]; + +i1 = i2; // Error +i1 = i3; +i1 = i4; // Error + +i2 = i1; // Error +i2 = i3; +i2 = i4; // Error + +i3 = i1; // Error +i3 = i2; // Error +i3 = i4; // Error + +i4 = i1; +i4 = i2; +i4 = i3; + +declare let o1: { [key: TaggedString1]: string }; +declare let o2: { [key: TaggedString2]: string }; +declare let o3: { [key: TaggedString1 | TaggedString2]: string }; +declare let o4: { [key: TaggedString1 & TaggedString2]: string }; + +o1[s0]; // Error +o1[s1]; +o1[s2]; // Error +o1[s3]; // Error +o1[s4]; + +o2[s0]; // Error +o2[s1]; // Error +o2[s2]; +o2[s3]; // Error +o2[s4]; + +o3[s0]; // Error +o3[s1]; +o3[s2]; +o3[s3]; +o3[s4]; + +o4[s0]; // Error +o4[s1]; // Error +o4[s2]; // Error +o4[s3]; // Error +o4[s4]; + +o1 = o2; +o1 = o3; +o1 = o4; + +o2 = o1; +o2 = o3; +o2 = o4; + +o3 = o1; +o3 = o2; +o3 = o4; + +o4 = o1; +o4 = o2; +o4 = o3; + +// Index signatures inferred from computed property names + +const obj10 = { + ['x']: 0 as const, + ['a' + 'b']: 1 as const, +}; + +const obj11 = { + [1]: 2 as const, + [1 + 2]: 3 as const, +}; + +const obj12 = { + [sym]: 4 as const, + [Symbol()]: 5 as const, +}; + +const obj13 = { + ['x']: 0 as const, + ['a' + 'b']: 1 as const, + [1]: 2 as const, + [1 + 2]: 3 as const, + [sym]: 4 as const, + [Symbol()]: 5 as const, +}; // Repros from #1863 @@ -242,26 +334,91 @@ const funcs = { sfoo: x => x.length, nfoo: x => x * 2, // n: number }; -obj1[s0]; // Error -obj1[s1]; -obj1[s2]; // Error -obj1[s3]; // Error -obj1[s4]; -obj2[s0]; // Error -obj2[s1]; -obj2[s2]; -obj2[s3]; // Error -obj2[s4]; -obj3[s0]; // Error -obj3[s1]; -obj3[s2]; -obj3[s3]; -obj3[s4]; -obj4[s0]; // Error -obj4[s1]; // Error -obj4[s2]; // Error -obj4[s3]; // Error -obj4[s4]; +i1[s0]; // Error +i1[s1]; +i1[s2]; // Error +i1[s3]; // Error +i1[s4]; +i2[s0]; // Error +i2[s1]; // Error +i2[s2]; +i2[s3]; // Error +i2[s4]; +i3[s0]; // Error +i3[s1]; +i3[s2]; +i3[s3]; +i3[s4]; +i4[s0]; // Error +i4[s1]; // Error +i4[s2]; // Error +i4[s3]; // Error +i4[s4]; +i1 = i2; // Error +i1 = i3; +i1 = i4; // Error +i2 = i1; // Error +i2 = i3; +i2 = i4; // Error +i3 = i1; // Error +i3 = i2; // Error +i3 = i4; // Error +i4 = i1; +i4 = i2; +i4 = i3; +o1[s0]; // Error +o1[s1]; +o1[s2]; // Error +o1[s3]; // Error +o1[s4]; +o2[s0]; // Error +o2[s1]; // Error +o2[s2]; +o2[s3]; // Error +o2[s4]; +o3[s0]; // Error +o3[s1]; +o3[s2]; +o3[s3]; +o3[s4]; +o4[s0]; // Error +o4[s1]; // Error +o4[s2]; // Error +o4[s3]; // Error +o4[s4]; +o1 = o2; +o1 = o3; +o1 = o4; +o2 = o1; +o2 = o3; +o2 = o4; +o3 = o1; +o3 = o2; +o3 = o4; +o4 = o1; +o4 = o2; +o4 = o3; +// Index signatures inferred from computed property names +const obj10 = { + ['x']: 0, + ['a' + 'b']: 1, +}; +const obj11 = { + [1]: 2, + [1 + 2]: 3, +}; +const obj12 = { + [sym]: 4, + [Symbol()]: 5, +}; +const obj13 = { + ['x']: 0, + ['a' + 'b']: 1, + [1]: 2, + [1 + 2]: 3, + [sym]: 4, + [Symbol()]: 5, +}; // Repros from #1863 const system = Symbol('system'); const SomeSytePlugin = Symbol('SomeSytePlugin'); @@ -378,23 +535,59 @@ declare type Tag2 = { }; declare type TaggedString1 = string & Tag1; declare type TaggedString2 = string & Tag2; -declare let obj1: { +declare let s0: string; +declare let s1: TaggedString1; +declare let s2: TaggedString2; +declare let s3: TaggedString1 | TaggedString2; +declare let s4: TaggedString1 & TaggedString2; +interface I1 { + [key: TaggedString1]: string; +} +interface I2 { + [key: TaggedString2]: string; +} +interface I3 { + [key: TaggedString1 | TaggedString2]: string; +} +interface I4 { + [key: TaggedString1 & TaggedString2]: string; +} +declare let i1: I1; +declare let i2: I2; +declare let i3: I3; +declare let i4: I4; +declare let o1: { [key: TaggedString1]: string; }; -declare let obj2: { +declare let o2: { [key: TaggedString2]: string; }; -declare let obj3: { +declare let o3: { [key: TaggedString1 | TaggedString2]: string; }; -declare let obj4: { +declare let o4: { [key: TaggedString1 & TaggedString2]: string; }; -declare let s0: string; -declare let s1: TaggedString1; -declare let s2: TaggedString2; -declare let s3: TaggedString1 | TaggedString2; -declare let s4: TaggedString1 & TaggedString2; +declare const obj10: { + [x: string]: 0 | 1; + x: 0; +}; +declare const obj11: { + [x: number]: 2 | 3; + 1: 2; +}; +declare const obj12: { + [x: symbol]: 4 | 5; + [sym]: 4; +}; +declare const obj13: { + [x: string]: 0 | 2 | 1 | 3; + [x: number]: 2 | 3; + [x: symbol]: 4 | 5; + x: 0; + 1: 2; + [sym]: 4; +}; declare const system: unique symbol; declare const SomeSytePlugin: unique symbol; interface Plugs { diff --git a/tests/baselines/reference/indexSignatures1.symbols b/tests/baselines/reference/indexSignatures1.symbols index feddd2bdf8d59..d28791772497f 100644 --- a/tests/baselines/reference/indexSignatures1.symbols +++ b/tests/baselines/reference/indexSignatures1.symbols @@ -249,334 +249,614 @@ type TaggedString2 = string & Tag2; >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) >Tag2 : Symbol(Tag2, Decl(indexSignatures1.ts, 94, 31)) -declare let obj1: { [key: TaggedString1]: string }; ->obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) ->key : Symbol(key, Decl(indexSignatures1.ts, 100, 21)) +declare let s0: string; +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +declare let s1: TaggedString1; +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) >TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) -declare let obj2: { [key: TaggedString2]: string }; ->obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) ->key : Symbol(key, Decl(indexSignatures1.ts, 101, 21)) +declare let s2: TaggedString2; +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; ->obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) ->key : Symbol(key, Decl(indexSignatures1.ts, 102, 21)) +declare let s3: TaggedString1 | TaggedString2; +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) >TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; ->obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) ->key : Symbol(key, Decl(indexSignatures1.ts, 103, 21)) +declare let s4: TaggedString1 & TaggedString2; +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) >TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -declare let s0: string; ->s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) +interface I1 { [key: TaggedString1]: string } +>I1 : Symbol(I1, Decl(indexSignatures1.ts, 104, 46)) +>key : Symbol(key, Decl(indexSignatures1.ts, 106, 16)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) -declare let s1: TaggedString1; ->s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) +interface I2 { [key: TaggedString2]: string } +>I2 : Symbol(I2, Decl(indexSignatures1.ts, 106, 45)) +>key : Symbol(key, Decl(indexSignatures1.ts, 107, 16)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +interface I3 { [key: TaggedString1 | TaggedString2]: string } +>I3 : Symbol(I3, Decl(indexSignatures1.ts, 107, 45)) +>key : Symbol(key, Decl(indexSignatures1.ts, 108, 16)) >TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -declare let s2: TaggedString2; ->s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) +interface I4 { [key: TaggedString1 & TaggedString2]: string } +>I4 : Symbol(I4, Decl(indexSignatures1.ts, 108, 61)) +>key : Symbol(key, Decl(indexSignatures1.ts, 109, 16)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -declare let s3: TaggedString1 | TaggedString2; ->s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) +declare let i1: I1; +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>I1 : Symbol(I1, Decl(indexSignatures1.ts, 104, 46)) + +declare let i2: I2; +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>I2 : Symbol(I2, Decl(indexSignatures1.ts, 106, 45)) + +declare let i3: I3; +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>I3 : Symbol(I3, Decl(indexSignatures1.ts, 107, 45)) + +declare let i4: I4; +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>I4 : Symbol(I4, Decl(indexSignatures1.ts, 108, 61)) + +i1[s0]; // Error +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +i1[s1]; +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +i1[s2]; // Error +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +i1[s3]; // Error +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +i1[s4]; +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +i2[s0]; // Error +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +i2[s1]; // Error +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +i2[s2]; +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +i2[s3]; // Error +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +i2[s4]; +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +i3[s0]; // Error +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +i3[s1]; +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +i3[s2]; +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +i3[s3]; +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +i3[s4]; +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +i4[s0]; // Error +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +i4[s1]; // Error +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +i4[s2]; // Error +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +i4[s3]; // Error +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +i4[s4]; +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +i1 = i2; // Error +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) + +i1 = i3; +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) + +i1 = i4; // Error +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) + +i2 = i1; // Error +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) + +i2 = i3; +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) + +i2 = i4; // Error +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) + +i3 = i1; // Error +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) + +i3 = i2; // Error +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) + +i3 = i4; // Error +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) + +i4 = i1; +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>i1 : Symbol(i1, Decl(indexSignatures1.ts, 111, 11)) + +i4 = i2; +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>i2 : Symbol(i2, Decl(indexSignatures1.ts, 112, 11)) + +i4 = i3; +>i4 : Symbol(i4, Decl(indexSignatures1.ts, 114, 11)) +>i3 : Symbol(i3, Decl(indexSignatures1.ts, 113, 11)) + +declare let o1: { [key: TaggedString1]: string }; +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 156, 19)) >TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) + +declare let o2: { [key: TaggedString2]: string }; +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 157, 19)) >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -declare let s4: TaggedString1 & TaggedString2; ->s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) +declare let o3: { [key: TaggedString1 | TaggedString2]: string }; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 158, 19)) +>TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) +>TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) + +declare let o4: { [key: TaggedString1 & TaggedString2]: string }; +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>key : Symbol(key, Decl(indexSignatures1.ts, 159, 19)) >TaggedString1 : Symbol(TaggedString1, Decl(indexSignatures1.ts, 95, 31)) >TaggedString2 : Symbol(TaggedString2, Decl(indexSignatures1.ts, 97, 35)) -obj1[s0]; // Error ->obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) ->s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) +o1[s0]; // Error +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +o1[s1]; +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +o1[s2]; // Error +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +o1[s3]; // Error +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +o1[s4]; +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +o2[s0]; // Error +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +o2[s1]; // Error +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +o2[s2]; +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +o2[s3]; // Error +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +o2[s4]; +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +o3[s0]; // Error +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +o3[s1]; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +o3[s2]; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) + +o3[s3]; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) + +o3[s4]; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) + +o4[s0]; // Error +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>s0 : Symbol(s0, Decl(indexSignatures1.ts, 100, 11)) + +o4[s1]; // Error +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>s1 : Symbol(s1, Decl(indexSignatures1.ts, 101, 11)) + +o4[s2]; // Error +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>s2 : Symbol(s2, Decl(indexSignatures1.ts, 102, 11)) -obj1[s1]; ->obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) ->s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) +o4[s3]; // Error +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>s3 : Symbol(s3, Decl(indexSignatures1.ts, 103, 11)) -obj1[s2]; // Error ->obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) ->s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) +o4[s4]; +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>s4 : Symbol(s4, Decl(indexSignatures1.ts, 104, 11)) -obj1[s3]; // Error ->obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) ->s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) +o1 = o2; +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) -obj1[s4]; ->obj1 : Symbol(obj1, Decl(indexSignatures1.ts, 100, 11)) ->s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) +o1 = o3; +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) -obj2[s0]; // Error ->obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) ->s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) +o1 = o4; +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) -obj2[s1]; ->obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) ->s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) +o2 = o1; +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) -obj2[s2]; ->obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) ->s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) +o2 = o3; +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) -obj2[s3]; // Error ->obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) ->s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) +o2 = o4; +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) -obj2[s4]; ->obj2 : Symbol(obj2, Decl(indexSignatures1.ts, 101, 11)) ->s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) +o3 = o1; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) -obj3[s0]; // Error ->obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) ->s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) +o3 = o2; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) -obj3[s1]; ->obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) ->s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) +o3 = o4; +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) -obj3[s2]; ->obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) ->s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) +o4 = o1; +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>o1 : Symbol(o1, Decl(indexSignatures1.ts, 156, 11)) -obj3[s3]; ->obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) ->s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) +o4 = o2; +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>o2 : Symbol(o2, Decl(indexSignatures1.ts, 157, 11)) -obj3[s4]; ->obj3 : Symbol(obj3, Decl(indexSignatures1.ts, 102, 11)) ->s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) +o4 = o3; +>o4 : Symbol(o4, Decl(indexSignatures1.ts, 159, 11)) +>o3 : Symbol(o3, Decl(indexSignatures1.ts, 158, 11)) -obj4[s0]; // Error ->obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) ->s0 : Symbol(s0, Decl(indexSignatures1.ts, 105, 11)) +// Index signatures inferred from computed property names -obj4[s1]; // Error ->obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) ->s1 : Symbol(s1, Decl(indexSignatures1.ts, 106, 11)) +const obj10 = { +>obj10 : Symbol(obj10, Decl(indexSignatures1.ts, 203, 5)) -obj4[s2]; // Error ->obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) ->s2 : Symbol(s2, Decl(indexSignatures1.ts, 107, 11)) + ['x']: 0 as const, +>['x'] : Symbol(['x'], Decl(indexSignatures1.ts, 203, 15)) +>'x' : Symbol(['x'], Decl(indexSignatures1.ts, 203, 15)) -obj4[s3]; // Error ->obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) ->s3 : Symbol(s3, Decl(indexSignatures1.ts, 108, 11)) + ['a' + 'b']: 1 as const, +>['a' + 'b'] : Symbol(['a' + 'b'], Decl(indexSignatures1.ts, 204, 22)) -obj4[s4]; ->obj4 : Symbol(obj4, Decl(indexSignatures1.ts, 103, 11)) ->s4 : Symbol(s4, Decl(indexSignatures1.ts, 109, 11)) +}; + +const obj11 = { +>obj11 : Symbol(obj11, Decl(indexSignatures1.ts, 208, 5)) + + [1]: 2 as const, +>[1] : Symbol([1], Decl(indexSignatures1.ts, 208, 15)) +>1 : Symbol([1], Decl(indexSignatures1.ts, 208, 15)) + + [1 + 2]: 3 as const, +>[1 + 2] : Symbol([1 + 2], Decl(indexSignatures1.ts, 209, 20)) + +}; + +const obj12 = { +>obj12 : Symbol(obj12, Decl(indexSignatures1.ts, 213, 5)) + + [sym]: 4 as const, +>[sym] : Symbol([sym], Decl(indexSignatures1.ts, 213, 15)) +>sym : Symbol(sym, Decl(indexSignatures1.ts, 2, 5)) + + [Symbol()]: 5 as const, +>[Symbol()] : Symbol([Symbol()], Decl(indexSignatures1.ts, 214, 22)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +}; + +const obj13 = { +>obj13 : Symbol(obj13, Decl(indexSignatures1.ts, 218, 5)) + + ['x']: 0 as const, +>['x'] : Symbol(['x'], Decl(indexSignatures1.ts, 218, 15)) +>'x' : Symbol(['x'], Decl(indexSignatures1.ts, 218, 15)) + + ['a' + 'b']: 1 as const, +>['a' + 'b'] : Symbol(['a' + 'b'], Decl(indexSignatures1.ts, 219, 22)) + + [1]: 2 as const, +>[1] : Symbol([1], Decl(indexSignatures1.ts, 220, 28)) +>1 : Symbol([1], Decl(indexSignatures1.ts, 220, 28)) + + [1 + 2]: 3 as const, +>[1 + 2] : Symbol([1 + 2], Decl(indexSignatures1.ts, 221, 20)) + + [sym]: 4 as const, +>[sym] : Symbol([sym], Decl(indexSignatures1.ts, 222, 24)) +>sym : Symbol(sym, Decl(indexSignatures1.ts, 2, 5)) + + [Symbol()]: 5 as const, +>[Symbol()] : Symbol([Symbol()], Decl(indexSignatures1.ts, 223, 22)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +}; // Repros from #1863 const system = Symbol('system'); ->system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 229, 5)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) const SomeSytePlugin = Symbol('SomeSytePlugin'); ->SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 138, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 230, 5)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) interface Plugs { ->Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 138, 48)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 230, 48)) [key: symbol]: (...args: any) => unknown; ->key : Symbol(key, Decl(indexSignatures1.ts, 141, 5)) ->args : Symbol(args, Decl(indexSignatures1.ts, 141, 20)) +>key : Symbol(key, Decl(indexSignatures1.ts, 233, 5)) +>args : Symbol(args, Decl(indexSignatures1.ts, 233, 20)) } const plugins = { ->plugins : Symbol(plugins, Decl(indexSignatures1.ts, 144, 5)) +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 236, 5)) "user": {} as Plugs, ->"user" : Symbol("user", Decl(indexSignatures1.ts, 144, 17)) ->Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 138, 48)) +>"user" : Symbol("user", Decl(indexSignatures1.ts, 236, 17)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 230, 48)) [system]: {} as Plugs ->[system] : Symbol([system], Decl(indexSignatures1.ts, 145, 24)) ->system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) ->Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 138, 48)) +>[system] : Symbol([system], Decl(indexSignatures1.ts, 237, 24)) +>system : Symbol(system, Decl(indexSignatures1.ts, 229, 5)) +>Plugs : Symbol(Plugs, Decl(indexSignatures1.ts, 230, 48)) }; plugins[system][SomeSytePlugin] = () => console.log('awsome'); ->plugins : Symbol(plugins, Decl(indexSignatures1.ts, 144, 5)) ->system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) ->SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 138, 5)) +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 236, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 229, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 230, 5)) >console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) >console : Symbol(console, Decl(lib.dom.d.ts, --, --)) >log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) plugins[system][SomeSytePlugin](); ->plugins : Symbol(plugins, Decl(indexSignatures1.ts, 144, 5)) ->system : Symbol(system, Decl(indexSignatures1.ts, 137, 5)) ->SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 138, 5)) +>plugins : Symbol(plugins, Decl(indexSignatures1.ts, 236, 5)) +>system : Symbol(system, Decl(indexSignatures1.ts, 229, 5)) +>SomeSytePlugin : Symbol(SomeSytePlugin, Decl(indexSignatures1.ts, 230, 5)) var theAnswer: symbol = Symbol('secret'); ->theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 152, 3)) +>theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 244, 3)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) var obj = {} as Record; ->obj : Symbol(obj, Decl(indexSignatures1.ts, 153, 3)) +>obj : Symbol(obj, Decl(indexSignatures1.ts, 245, 3)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) obj[theAnswer] = 42; ->obj : Symbol(obj, Decl(indexSignatures1.ts, 153, 3)) ->theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 152, 3)) +>obj : Symbol(obj, Decl(indexSignatures1.ts, 245, 3)) +>theAnswer : Symbol(theAnswer, Decl(indexSignatures1.ts, 244, 3)) // Repro from #26470 const directive = Symbol('directive'); ->directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 250, 5)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) declare function foo(options: { [x in string]: (arg: TArg) => TRet } & { [directive]?: TDir }): void; ->foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) ->TArg : Symbol(TArg, Decl(indexSignatures1.ts, 159, 21)) ->TRet : Symbol(TRet, Decl(indexSignatures1.ts, 159, 26)) ->TDir : Symbol(TDir, Decl(indexSignatures1.ts, 159, 32)) ->options : Symbol(options, Decl(indexSignatures1.ts, 159, 39)) ->x : Symbol(x, Decl(indexSignatures1.ts, 159, 51)) ->arg : Symbol(arg, Decl(indexSignatures1.ts, 159, 66)) ->TArg : Symbol(TArg, Decl(indexSignatures1.ts, 159, 21)) ->TRet : Symbol(TRet, Decl(indexSignatures1.ts, 159, 26)) ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 159, 90)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) ->TDir : Symbol(TDir, Decl(indexSignatures1.ts, 159, 32)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 250, 38)) +>TArg : Symbol(TArg, Decl(indexSignatures1.ts, 251, 21)) +>TRet : Symbol(TRet, Decl(indexSignatures1.ts, 251, 26)) +>TDir : Symbol(TDir, Decl(indexSignatures1.ts, 251, 32)) +>options : Symbol(options, Decl(indexSignatures1.ts, 251, 39)) +>x : Symbol(x, Decl(indexSignatures1.ts, 251, 51)) +>arg : Symbol(arg, Decl(indexSignatures1.ts, 251, 66)) +>TArg : Symbol(TArg, Decl(indexSignatures1.ts, 251, 21)) +>TRet : Symbol(TRet, Decl(indexSignatures1.ts, 251, 26)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 251, 90)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 250, 5)) +>TDir : Symbol(TDir, Decl(indexSignatures1.ts, 251, 32)) let case1 = foo({ ->case1 : Symbol(case1, Decl(indexSignatures1.ts, 161, 3)) ->foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) +>case1 : Symbol(case1, Decl(indexSignatures1.ts, 253, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 250, 38)) [directive]: (x: string) => 'str', ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 161, 17)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) ->x : Symbol(x, Decl(indexSignatures1.ts, 162, 18)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 253, 17)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 250, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 254, 18)) addOne: (x: number) => x + 1, ->addOne : Symbol(addOne, Decl(indexSignatures1.ts, 162, 38)) ->x : Symbol(x, Decl(indexSignatures1.ts, 163, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 163, 13)) +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 254, 38)) +>x : Symbol(x, Decl(indexSignatures1.ts, 255, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 255, 13)) double: (x: number) => x + x, ->double : Symbol(double, Decl(indexSignatures1.ts, 163, 33)) ->x : Symbol(x, Decl(indexSignatures1.ts, 164, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 164, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 164, 13)) +>double : Symbol(double, Decl(indexSignatures1.ts, 255, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 256, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 256, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 256, 13)) }); let case2 = foo({ ->case2 : Symbol(case2, Decl(indexSignatures1.ts, 167, 3)) ->foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) +>case2 : Symbol(case2, Decl(indexSignatures1.ts, 259, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 250, 38)) addOne: (x: number) => x + 1, ->addOne : Symbol(addOne, Decl(indexSignatures1.ts, 167, 17)) ->x : Symbol(x, Decl(indexSignatures1.ts, 168, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 168, 13)) +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 259, 17)) +>x : Symbol(x, Decl(indexSignatures1.ts, 260, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 260, 13)) double: (x: number) => x + x, ->double : Symbol(double, Decl(indexSignatures1.ts, 168, 33)) ->x : Symbol(x, Decl(indexSignatures1.ts, 169, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 169, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 169, 13)) +>double : Symbol(double, Decl(indexSignatures1.ts, 260, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 261, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 261, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 261, 13)) [directive]: (x: string) => 'str', ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 169, 33)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) ->x : Symbol(x, Decl(indexSignatures1.ts, 170, 18)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 261, 33)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 250, 5)) +>x : Symbol(x, Decl(indexSignatures1.ts, 262, 18)) }); let case3 = foo({ ->case3 : Symbol(case3, Decl(indexSignatures1.ts, 173, 3)) ->foo : Symbol(foo, Decl(indexSignatures1.ts, 158, 38)) +>case3 : Symbol(case3, Decl(indexSignatures1.ts, 265, 3)) +>foo : Symbol(foo, Decl(indexSignatures1.ts, 250, 38)) [directive]: 'str', ->[directive] : Symbol([directive], Decl(indexSignatures1.ts, 173, 17)) ->directive : Symbol(directive, Decl(indexSignatures1.ts, 158, 5)) +>[directive] : Symbol([directive], Decl(indexSignatures1.ts, 265, 17)) +>directive : Symbol(directive, Decl(indexSignatures1.ts, 250, 5)) addOne: (x: number) => x + 1, ->addOne : Symbol(addOne, Decl(indexSignatures1.ts, 174, 23)) ->x : Symbol(x, Decl(indexSignatures1.ts, 175, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 175, 13)) +>addOne : Symbol(addOne, Decl(indexSignatures1.ts, 266, 23)) +>x : Symbol(x, Decl(indexSignatures1.ts, 267, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 267, 13)) double: (x: number) => x + x, ->double : Symbol(double, Decl(indexSignatures1.ts, 175, 33)) ->x : Symbol(x, Decl(indexSignatures1.ts, 176, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 176, 13)) ->x : Symbol(x, Decl(indexSignatures1.ts, 176, 13)) +>double : Symbol(double, Decl(indexSignatures1.ts, 267, 33)) +>x : Symbol(x, Decl(indexSignatures1.ts, 268, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 268, 13)) +>x : Symbol(x, Decl(indexSignatures1.ts, 268, 13)) }); // Repros from #42192 type Pseudo = `&:${string}`; ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 269, 3)) const AmIPseudo1: Pseudo = '&:test'; ->AmIPseudo1 : Symbol(AmIPseudo1, Decl(indexSignatures1.ts, 183, 5)) ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) +>AmIPseudo1 : Symbol(AmIPseudo1, Decl(indexSignatures1.ts, 275, 5)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 269, 3)) const AmIPseudo: Pseudo = '&'; // Error ->AmIPseudo : Symbol(AmIPseudo, Decl(indexSignatures1.ts, 184, 5)) ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) +>AmIPseudo : Symbol(AmIPseudo, Decl(indexSignatures1.ts, 276, 5)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 269, 3)) type PseudoDeclaration = { [key in Pseudo]: string }; ->PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 184, 30)) ->key : Symbol(key, Decl(indexSignatures1.ts, 186, 28)) ->Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 177, 3)) +>PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 276, 30)) +>key : Symbol(key, Decl(indexSignatures1.ts, 278, 28)) +>Pseudo : Symbol(Pseudo, Decl(indexSignatures1.ts, 269, 3)) const test: PseudoDeclaration = { 'someKey' : 'someValue' }; // Error ->test : Symbol(test, Decl(indexSignatures1.ts, 188, 5)) ->PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 184, 30)) ->'someKey' : Symbol('someKey', Decl(indexSignatures1.ts, 188, 33)) +>test : Symbol(test, Decl(indexSignatures1.ts, 280, 5)) +>PseudoDeclaration : Symbol(PseudoDeclaration, Decl(indexSignatures1.ts, 276, 30)) +>'someKey' : Symbol('someKey', Decl(indexSignatures1.ts, 280, 33)) type FieldPattern = `/${string}`; ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 280, 60)) const path1: FieldPattern = '/one'; ->path1 : Symbol(path1, Decl(indexSignatures1.ts, 192, 5)) ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) +>path1 : Symbol(path1, Decl(indexSignatures1.ts, 284, 5)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 280, 60)) const path2: FieldPattern = 'two'; // Error ->path2 : Symbol(path2, Decl(indexSignatures1.ts, 193, 5)) ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) +>path2 : Symbol(path2, Decl(indexSignatures1.ts, 285, 5)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 280, 60)) type PathsObject = { [P in FieldPattern]: object; }; ->PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 193, 34)) ->P : Symbol(P, Decl(indexSignatures1.ts, 195, 22)) ->FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 188, 60)) +>PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 285, 34)) +>P : Symbol(P, Decl(indexSignatures1.ts, 287, 22)) +>FieldPattern : Symbol(FieldPattern, Decl(indexSignatures1.ts, 280, 60)) const pathObject: PathsObject = 123; // Error ->pathObject : Symbol(pathObject, Decl(indexSignatures1.ts, 196, 5)) ->PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 193, 34)) +>pathObject : Symbol(pathObject, Decl(indexSignatures1.ts, 288, 5)) +>PathsObject : Symbol(PathsObject, Decl(indexSignatures1.ts, 285, 34)) type IdType = `${number}-${number}-${number}-${number}` ->IdType : Symbol(IdType, Decl(indexSignatures1.ts, 196, 36)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 288, 36)) const id: IdType = '0000-0000-0000-0001'; ->id : Symbol(id, Decl(indexSignatures1.ts, 199, 5)) ->IdType : Symbol(IdType, Decl(indexSignatures1.ts, 196, 36)) +>id : Symbol(id, Decl(indexSignatures1.ts, 291, 5)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 288, 36)) type A = Record; ->A : Symbol(A, Decl(indexSignatures1.ts, 199, 41)) +>A : Symbol(A, Decl(indexSignatures1.ts, 291, 41)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->IdType : Symbol(IdType, Decl(indexSignatures1.ts, 196, 36)) +>IdType : Symbol(IdType, Decl(indexSignatures1.ts, 288, 36)) const a: A = { [id]: 'test' } ->a : Symbol(a, Decl(indexSignatures1.ts, 203, 5)) ->A : Symbol(A, Decl(indexSignatures1.ts, 199, 41)) ->[id] : Symbol([id], Decl(indexSignatures1.ts, 203, 14)) ->id : Symbol(id, Decl(indexSignatures1.ts, 199, 5)) +>a : Symbol(a, Decl(indexSignatures1.ts, 295, 5)) +>A : Symbol(A, Decl(indexSignatures1.ts, 291, 41)) +>[id] : Symbol([id], Decl(indexSignatures1.ts, 295, 14)) +>id : Symbol(id, Decl(indexSignatures1.ts, 291, 5)) let aid = a[id]; ->aid : Symbol(aid, Decl(indexSignatures1.ts, 205, 3)) ->a : Symbol(a, Decl(indexSignatures1.ts, 203, 5)) ->id : Symbol(id, Decl(indexSignatures1.ts, 199, 5)) +>aid : Symbol(aid, Decl(indexSignatures1.ts, 297, 3)) +>a : Symbol(a, Decl(indexSignatures1.ts, 295, 5)) +>id : Symbol(id, Decl(indexSignatures1.ts, 291, 5)) diff --git a/tests/baselines/reference/indexSignatures1.types b/tests/baselines/reference/indexSignatures1.types index e802b7fc7eecf..4514d0a34b71b 100644 --- a/tests/baselines/reference/indexSignatures1.types +++ b/tests/baselines/reference/indexSignatures1.types @@ -278,137 +278,489 @@ type TaggedString1 = string & Tag1; type TaggedString2 = string & Tag2; >TaggedString2 : TaggedString2 -declare let obj1: { [key: TaggedString1]: string }; ->obj1 : { [key: TaggedString1]: string; } +declare let s0: string; +>s0 : string + +declare let s1: TaggedString1; +>s1 : TaggedString1 + +declare let s2: TaggedString2; +>s2 : TaggedString2 + +declare let s3: TaggedString1 | TaggedString2; +>s3 : TaggedString1 | TaggedString2 + +declare let s4: TaggedString1 & TaggedString2; +>s4 : string & Tag1 & Tag2 + +interface I1 { [key: TaggedString1]: string } >key : TaggedString1 -declare let obj2: { [key: TaggedString2]: string }; ->obj2 : { [key: TaggedString2]: string; } +interface I2 { [key: TaggedString2]: string } >key : TaggedString2 -declare let obj3: { [key: TaggedString1 | TaggedString2]: string }; ->obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +interface I3 { [key: TaggedString1 | TaggedString2]: string } >key : TaggedString1 | TaggedString2 -declare let obj4: { [key: TaggedString1 & TaggedString2]: string }; ->obj4 : { [key: string & Tag1 & Tag2]: string; } +interface I4 { [key: TaggedString1 & TaggedString2]: string } >key : string & Tag1 & Tag2 -declare let s0: string; +declare let i1: I1; +>i1 : I1 + +declare let i2: I2; +>i2 : I2 + +declare let i3: I3; +>i3 : I3 + +declare let i4: I4; +>i4 : I4 + +i1[s0]; // Error +>i1[s0] : any +>i1 : I1 >s0 : string -declare let s1: TaggedString1; +i1[s1]; +>i1[s1] : string +>i1 : I1 >s1 : TaggedString1 -declare let s2: TaggedString2; +i1[s2]; // Error +>i1[s2] : any +>i1 : I1 >s2 : TaggedString2 -declare let s3: TaggedString1 | TaggedString2; +i1[s3]; // Error +>i1[s3] : any +>i1 : I1 >s3 : TaggedString1 | TaggedString2 -declare let s4: TaggedString1 & TaggedString2; +i1[s4]; +>i1[s4] : string +>i1 : I1 +>s4 : string & Tag1 & Tag2 + +i2[s0]; // Error +>i2[s0] : any +>i2 : I2 +>s0 : string + +i2[s1]; // Error +>i2[s1] : any +>i2 : I2 +>s1 : TaggedString1 + +i2[s2]; +>i2[s2] : string +>i2 : I2 +>s2 : TaggedString2 + +i2[s3]; // Error +>i2[s3] : any +>i2 : I2 +>s3 : TaggedString1 | TaggedString2 + +i2[s4]; +>i2[s4] : string +>i2 : I2 +>s4 : string & Tag1 & Tag2 + +i3[s0]; // Error +>i3[s0] : any +>i3 : I3 +>s0 : string + +i3[s1]; +>i3[s1] : string +>i3 : I3 +>s1 : TaggedString1 + +i3[s2]; +>i3[s2] : string +>i3 : I3 +>s2 : TaggedString2 + +i3[s3]; +>i3[s3] : string +>i3 : I3 +>s3 : TaggedString1 | TaggedString2 + +i3[s4]; +>i3[s4] : string +>i3 : I3 +>s4 : string & Tag1 & Tag2 + +i4[s0]; // Error +>i4[s0] : any +>i4 : I4 +>s0 : string + +i4[s1]; // Error +>i4[s1] : any +>i4 : I4 +>s1 : TaggedString1 + +i4[s2]; // Error +>i4[s2] : any +>i4 : I4 +>s2 : TaggedString2 + +i4[s3]; // Error +>i4[s3] : any +>i4 : I4 +>s3 : TaggedString1 | TaggedString2 + +i4[s4]; +>i4[s4] : string +>i4 : I4 >s4 : string & Tag1 & Tag2 -obj1[s0]; // Error ->obj1[s0] : any ->obj1 : { [key: TaggedString1]: string; } +i1 = i2; // Error +>i1 = i2 : I2 +>i1 : I1 +>i2 : I2 + +i1 = i3; +>i1 = i3 : I3 +>i1 : I1 +>i3 : I3 + +i1 = i4; // Error +>i1 = i4 : I4 +>i1 : I1 +>i4 : I4 + +i2 = i1; // Error +>i2 = i1 : I1 +>i2 : I2 +>i1 : I1 + +i2 = i3; +>i2 = i3 : I3 +>i2 : I2 +>i3 : I3 + +i2 = i4; // Error +>i2 = i4 : I4 +>i2 : I2 +>i4 : I4 + +i3 = i1; // Error +>i3 = i1 : I1 +>i3 : I3 +>i1 : I1 + +i3 = i2; // Error +>i3 = i2 : I2 +>i3 : I3 +>i2 : I2 + +i3 = i4; // Error +>i3 = i4 : I4 +>i3 : I3 +>i4 : I4 + +i4 = i1; +>i4 = i1 : I1 +>i4 : I4 +>i1 : I1 + +i4 = i2; +>i4 = i2 : I2 +>i4 : I4 +>i2 : I2 + +i4 = i3; +>i4 = i3 : I3 +>i4 : I4 +>i3 : I3 + +declare let o1: { [key: TaggedString1]: string }; +>o1 : { [key: TaggedString1]: string; } +>key : TaggedString1 + +declare let o2: { [key: TaggedString2]: string }; +>o2 : { [key: TaggedString2]: string; } +>key : TaggedString2 + +declare let o3: { [key: TaggedString1 | TaggedString2]: string }; +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>key : TaggedString1 | TaggedString2 + +declare let o4: { [key: TaggedString1 & TaggedString2]: string }; +>o4 : { [key: string & Tag1 & Tag2]: string; } +>key : string & Tag1 & Tag2 + +o1[s0]; // Error +>o1[s0] : any +>o1 : { [key: TaggedString1]: string; } >s0 : string -obj1[s1]; ->obj1[s1] : string ->obj1 : { [key: TaggedString1]: string; } +o1[s1]; +>o1[s1] : string +>o1 : { [key: TaggedString1]: string; } >s1 : TaggedString1 -obj1[s2]; // Error ->obj1[s2] : any ->obj1 : { [key: TaggedString1]: string; } +o1[s2]; // Error +>o1[s2] : any +>o1 : { [key: TaggedString1]: string; } >s2 : TaggedString2 -obj1[s3]; // Error ->obj1[s3] : any ->obj1 : { [key: TaggedString1]: string; } +o1[s3]; // Error +>o1[s3] : any +>o1 : { [key: TaggedString1]: string; } >s3 : TaggedString1 | TaggedString2 -obj1[s4]; ->obj1[s4] : string ->obj1 : { [key: TaggedString1]: string; } +o1[s4]; +>o1[s4] : string +>o1 : { [key: TaggedString1]: string; } >s4 : string & Tag1 & Tag2 -obj2[s0]; // Error ->obj2[s0] : any ->obj2 : { [key: TaggedString2]: string; } +o2[s0]; // Error +>o2[s0] : any +>o2 : { [key: TaggedString2]: string; } >s0 : string -obj2[s1]; ->obj2[s1] : any ->obj2 : { [key: TaggedString2]: string; } +o2[s1]; // Error +>o2[s1] : any +>o2 : { [key: TaggedString2]: string; } >s1 : TaggedString1 -obj2[s2]; ->obj2[s2] : string ->obj2 : { [key: TaggedString2]: string; } +o2[s2]; +>o2[s2] : string +>o2 : { [key: TaggedString2]: string; } >s2 : TaggedString2 -obj2[s3]; // Error ->obj2[s3] : any ->obj2 : { [key: TaggedString2]: string; } +o2[s3]; // Error +>o2[s3] : any +>o2 : { [key: TaggedString2]: string; } >s3 : TaggedString1 | TaggedString2 -obj2[s4]; ->obj2[s4] : string ->obj2 : { [key: TaggedString2]: string; } +o2[s4]; +>o2[s4] : string +>o2 : { [key: TaggedString2]: string; } >s4 : string & Tag1 & Tag2 -obj3[s0]; // Error ->obj3[s0] : any ->obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +o3[s0]; // Error +>o3[s0] : any +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } >s0 : string -obj3[s1]; ->obj3[s1] : string ->obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +o3[s1]; +>o3[s1] : string +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } >s1 : TaggedString1 -obj3[s2]; ->obj3[s2] : string ->obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +o3[s2]; +>o3[s2] : string +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } >s2 : TaggedString2 -obj3[s3]; ->obj3[s3] : string ->obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +o3[s3]; +>o3[s3] : string +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } >s3 : TaggedString1 | TaggedString2 -obj3[s4]; ->obj3[s4] : string ->obj3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +o3[s4]; +>o3[s4] : string +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } >s4 : string & Tag1 & Tag2 -obj4[s0]; // Error ->obj4[s0] : any ->obj4 : { [key: string & Tag1 & Tag2]: string; } +o4[s0]; // Error +>o4[s0] : any +>o4 : { [key: string & Tag1 & Tag2]: string; } >s0 : string -obj4[s1]; // Error ->obj4[s1] : any ->obj4 : { [key: string & Tag1 & Tag2]: string; } +o4[s1]; // Error +>o4[s1] : any +>o4 : { [key: string & Tag1 & Tag2]: string; } >s1 : TaggedString1 -obj4[s2]; // Error ->obj4[s2] : any ->obj4 : { [key: string & Tag1 & Tag2]: string; } +o4[s2]; // Error +>o4[s2] : any +>o4 : { [key: string & Tag1 & Tag2]: string; } >s2 : TaggedString2 -obj4[s3]; // Error ->obj4[s3] : any ->obj4 : { [key: string & Tag1 & Tag2]: string; } +o4[s3]; // Error +>o4[s3] : any +>o4 : { [key: string & Tag1 & Tag2]: string; } >s3 : TaggedString1 | TaggedString2 -obj4[s4]; ->obj4[s4] : string ->obj4 : { [key: string & Tag1 & Tag2]: string; } +o4[s4]; +>o4[s4] : string +>o4 : { [key: string & Tag1 & Tag2]: string; } >s4 : string & Tag1 & Tag2 +o1 = o2; +>o1 = o2 : { [key: TaggedString2]: string; } +>o1 : { [key: TaggedString1]: string; } +>o2 : { [key: TaggedString2]: string; } + +o1 = o3; +>o1 = o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>o1 : { [key: TaggedString1]: string; } +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } + +o1 = o4; +>o1 = o4 : { [key: string & Tag1 & Tag2]: string; } +>o1 : { [key: TaggedString1]: string; } +>o4 : { [key: string & Tag1 & Tag2]: string; } + +o2 = o1; +>o2 = o1 : { [key: TaggedString1]: string; } +>o2 : { [key: TaggedString2]: string; } +>o1 : { [key: TaggedString1]: string; } + +o2 = o3; +>o2 = o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>o2 : { [key: TaggedString2]: string; } +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } + +o2 = o4; +>o2 = o4 : { [key: string & Tag1 & Tag2]: string; } +>o2 : { [key: TaggedString2]: string; } +>o4 : { [key: string & Tag1 & Tag2]: string; } + +o3 = o1; +>o3 = o1 : { [key: TaggedString1]: string; } +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>o1 : { [key: TaggedString1]: string; } + +o3 = o2; +>o3 = o2 : { [key: TaggedString2]: string; } +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>o2 : { [key: TaggedString2]: string; } + +o3 = o4; +>o3 = o4 : { [key: string & Tag1 & Tag2]: string; } +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>o4 : { [key: string & Tag1 & Tag2]: string; } + +o4 = o1; +>o4 = o1 : { [key: TaggedString1]: string; } +>o4 : { [key: string & Tag1 & Tag2]: string; } +>o1 : { [key: TaggedString1]: string; } + +o4 = o2; +>o4 = o2 : { [key: TaggedString2]: string; } +>o4 : { [key: string & Tag1 & Tag2]: string; } +>o2 : { [key: TaggedString2]: string; } + +o4 = o3; +>o4 = o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } +>o4 : { [key: string & Tag1 & Tag2]: string; } +>o3 : { [key: TaggedString1]: string; [key: TaggedString2]: string; } + +// Index signatures inferred from computed property names + +const obj10 = { +>obj10 : { [x: string]: 0 | 1; x: 0; } +>{ ['x']: 0 as const, ['a' + 'b']: 1 as const,} : { [x: string]: 0 | 1; x: 0; } + + ['x']: 0 as const, +>['x'] : 0 +>'x' : "x" +>0 as const : 0 +>0 : 0 + + ['a' + 'b']: 1 as const, +>['a' + 'b'] : 1 +>'a' + 'b' : string +>'a' : "a" +>'b' : "b" +>1 as const : 1 +>1 : 1 + +}; + +const obj11 = { +>obj11 : { [x: number]: 2 | 3; 1: 2; } +>{ [1]: 2 as const, [1 + 2]: 3 as const,} : { [x: number]: 2 | 3; 1: 2; } + + [1]: 2 as const, +>[1] : 2 +>1 : 1 +>2 as const : 2 +>2 : 2 + + [1 + 2]: 3 as const, +>[1 + 2] : 3 +>1 + 2 : number +>1 : 1 +>2 : 2 +>3 as const : 3 +>3 : 3 + +}; + +const obj12 = { +>obj12 : { [x: symbol]: 4 | 5; [sym]: 4; } +>{ [sym]: 4 as const, [Symbol()]: 5 as const,} : { [x: symbol]: 4 | 5; [sym]: 4; } + + [sym]: 4 as const, +>[sym] : 4 +>sym : unique symbol +>4 as const : 4 +>4 : 4 + + [Symbol()]: 5 as const, +>[Symbol()] : 5 +>Symbol() : symbol +>Symbol : SymbolConstructor +>5 as const : 5 +>5 : 5 + +}; + +const obj13 = { +>obj13 : { [x: string]: 0 | 2 | 1 | 3; [x: number]: 2 | 3; [x: symbol]: 4 | 5; x: 0; 1: 2; [sym]: 4; } +>{ ['x']: 0 as const, ['a' + 'b']: 1 as const, [1]: 2 as const, [1 + 2]: 3 as const, [sym]: 4 as const, [Symbol()]: 5 as const,} : { [x: string]: 0 | 2 | 1 | 3; [x: number]: 2 | 3; [x: symbol]: 4 | 5; x: 0; 1: 2; [sym]: 4; } + + ['x']: 0 as const, +>['x'] : 0 +>'x' : "x" +>0 as const : 0 +>0 : 0 + + ['a' + 'b']: 1 as const, +>['a' + 'b'] : 1 +>'a' + 'b' : string +>'a' : "a" +>'b' : "b" +>1 as const : 1 +>1 : 1 + + [1]: 2 as const, +>[1] : 2 +>1 : 1 +>2 as const : 2 +>2 : 2 + + [1 + 2]: 3 as const, +>[1 + 2] : 3 +>1 + 2 : number +>1 : 1 +>2 : 2 +>3 as const : 3 +>3 : 3 + + [sym]: 4 as const, +>[sym] : 4 +>sym : unique symbol +>4 as const : 4 +>4 : 4 + + [Symbol()]: 5 as const, +>[Symbol()] : 5 +>Symbol() : symbol +>Symbol : SymbolConstructor +>5 as const : 5 +>5 : 5 + +}; + // Repros from #1863 const system = Symbol('system'); From fbffa7c3a089fe6edf6cf6b4512dcc4533fe4096 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 19 Jun 2021 12:26:52 -0700 Subject: [PATCH 54/56] Implement Go To Definition for all applicable index signatures --- src/compiler/checker.ts | 19 +++++++++++++++++-- src/compiler/types.ts | 2 ++ src/services/goToDefinition.ts | 7 +------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 67489269f4bfa..45328df7aaf47 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -417,6 +417,7 @@ namespace ts { }, getTypeOfPropertyOfType: (type, name) => getTypeOfPropertyOfType(type, escapeLeadingUnderscores(name)), getIndexInfoOfType: (type, kind) => getIndexInfoOfType(type, kind === IndexKind.String ? stringType : numberType), + getIndexInfosOfType, getSignaturesOfType, getIndexTypeOfType: (type, kind) => getIndexTypeOfType(type, kind === IndexKind.String ? stringType : numberType), getBaseTypes, @@ -452,6 +453,10 @@ namespace ts { // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors return node ? getSymbolAtLocation(node, /*ignoreErrors*/ true) : undefined; }, + getIndexInfosAtLocation: nodeIn => { + const node = getParseTreeNode(nodeIn); + return node ? getIndexInfosAtLocation(node) : undefined; + }, getShorthandAssignmentValueSymbol: nodeIn => { const node = getParseTreeNode(nodeIn); return node ? getShorthandAssignmentValueSymbol(node) : undefined; @@ -12016,12 +12021,12 @@ namespace ts { undefined; } - function isApplicableIndexType(source: Type, target: Type) { + function isApplicableIndexType(source: Type, target: Type): boolean { // A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index // signature applies to types assignable to 'number' and numeric string literal types. return isTypeAssignableTo(source, target) || target === stringType && isTypeAssignableTo(source, numberType) || - target === numberType && source.flags & TypeFlags.StringLiteral && isNumericLiteralName((source as StringLiteralType).value); + target === numberType && !!(source.flags & TypeFlags.StringLiteral) && isNumericLiteralName((source as StringLiteralType).value); } function getIndexInfosOfStructuredType(type: Type): readonly IndexInfo[] { @@ -39542,6 +39547,16 @@ namespace ts { } } + function getIndexInfosAtLocation(node: Node): readonly IndexInfo[] | undefined { + if (isIdentifier(node) && isPropertyAccessExpression(node.parent) && node.parent.name === node) { + const keyType = getLiteralTypeFromPropertyName(node); + const objectType = getTypeOfExpression(node.parent.expression); + const objectTypes = objectType.flags & TypeFlags.Union ? (objectType as UnionType).types : [objectType]; + return flatMap(objectTypes, t => filter(getIndexInfosOfType(t), info => isApplicableIndexType(keyType, info.keyType))); + } + return undefined; + } + function getShorthandAssignmentValueSymbol(location: Node | undefined): Symbol | undefined { if (location && location.kind === SyntaxKind.ShorthandPropertyAssignment) { return resolveEntityName((location as ShorthandPropertyAssignment).name, SymbolFlags.Value | SymbolFlags.Alias); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6b41f78bd7ebb..f0099c4f6199f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4088,6 +4088,7 @@ namespace ts { getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined; /* @internal */ getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; + getIndexInfosOfType(type: Type): readonly IndexInfo[]; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; getBaseTypes(type: InterfaceType): BaseType[]; @@ -4132,6 +4133,7 @@ namespace ts { getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; getSymbolAtLocation(node: Node): Symbol | undefined; + /* @internal */ getIndexInfosAtLocation(node: Node): readonly IndexInfo[] | undefined; getSymbolsOfParameterPropertyDeclaration(parameter: ParameterDeclaration, parameterName: string): Symbol[]; /** * The function returns the value (local variable) symbol of an identifier in the short-hand property assignment. diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 1ece63e531790..9fa856675197a 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -212,12 +212,7 @@ namespace ts.GoToDefinition { // At 'x.foo', see if the type of 'x' has an index signature, and if so find its declarations. function getDefinitionInfoForIndexSignatures(node: Node, checker: TypeChecker): DefinitionInfo[] | undefined { - if (!isPropertyAccessExpression(node.parent) || node.parent.name !== node) return; - const type = checker.getTypeAtLocation(node.parent.expression); - return mapDefined(type.isUnionOrIntersection() ? type.types : [type], nonUnionType => { - const info = checker.getIndexInfoOfType(nonUnionType, IndexKind.String); - return info && info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration); - }); + return mapDefined(checker.getIndexInfosAtLocation(node), info => info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration)); } function getSymbol(node: Node, checker: TypeChecker): Symbol | undefined { From 128e12511cd440d6369d883976fd594780ece115 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 19 Jun 2021 12:27:01 -0700 Subject: [PATCH 55/56] Add fourslash test --- tests/cases/fourslash/goToDefinitionIndexSignature.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/cases/fourslash/goToDefinitionIndexSignature.ts b/tests/cases/fourslash/goToDefinitionIndexSignature.ts index d5438830dc050..169e3580aea53 100644 --- a/tests/cases/fourslash/goToDefinitionIndexSignature.ts +++ b/tests/cases/fourslash/goToDefinitionIndexSignature.ts @@ -6,10 +6,21 @@ ////interface J { //// /*defJ*/[x: string]: number; ////} +////interface K { +//// /*defa*/[x: `a${string}`]: string; +//// /*defb*/[x: `${string}b`]: string; +////} ////declare const i: I; ////i.[|/*useI*/foo|]; ////declare const ij: I | J; ////ij.[|/*useIJ*/foo|]; +////declare const k: K; +////k.[|/*usea*/a|]; +////k.[|/*useb*/b|]; +////k.[|/*useab*/ab|]; verify.goToDefinition("useI", ["defI"]); verify.goToDefinition("useIJ", ["defI", "defJ"]); +verify.goToDefinition("usea", ["defa"]); +verify.goToDefinition("useb", ["defb"]); +verify.goToDefinition("useab", ["defa", "defb"]); From 1e376a5e99a162dfd6d9c38850000a0b3f3974d1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 19 Jun 2021 12:32:15 -0700 Subject: [PATCH 56/56] Accept new API baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d61c170a88633..7f30f901a9a16 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2192,6 +2192,7 @@ declare namespace ts { getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; + getIndexInfosOfType(type: Type): readonly IndexInfo[]; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; getBaseTypes(type: InterfaceType): BaseType[]; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 5df91e3708d40..cabab4bf61bfc 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2192,6 +2192,7 @@ declare namespace ts { getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; getPrivateIdentifierPropertyOfType(leftType: Type, name: string, location: Node): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; + getIndexInfosOfType(type: Type): readonly IndexInfo[]; getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; getBaseTypes(type: InterfaceType): BaseType[];