diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ee59b8862bf6..465371d0517a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -707,6 +707,13 @@ namespace ts { Signature = 1 << 0, // Obtaining contextual signature } + const enum AccessFlags { + None = 0, + NoIndexSignatures = 1 << 0, + Writing = 1 << 1, + CacheSymbol = 1 << 2, + } + const enum CallbackCheck { None, Bivariant, @@ -7235,7 +7242,15 @@ namespace ts { return getIndexType(getApparentType((type).type)); } if (type.flags & TypeFlags.Conditional) { - return getLowerBoundOfConditionalType(type); + if ((type).root.isDistributive) { + const checkType = (type).checkType; + const constraint = getLowerBoundOfKeyType(checkType); + if (constraint !== checkType) { + const mapper = makeUnaryTypeMapper((type).root.checkType, constraint); + return getConditionalTypeInstantiation(type, combineTypeMappers(mapper, (type).mapper)); + } + } + return type; } if (type.flags & TypeFlags.Union) { return getUnionType(sameMap((type).types, getLowerBoundOfKeyType)); @@ -7246,17 +7261,6 @@ namespace ts { return neverType; } - function getLowerBoundOfConditionalType(type: ConditionalType) { - if (type.root.isDistributive) { - const constraint = getLowerBoundOfKeyType(type.checkType); - if (constraint !== type.checkType) { - const mapper = makeUnaryTypeMapper(type.root.checkType, constraint); - return getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper)); - } - } - return type; - } - /** Resolve the members of a mapped type { [P in K]: T } */ function resolveMappedTypeMembers(type: MappedType) { const members: SymbolTable = createSymbolTable(); @@ -7525,15 +7529,18 @@ namespace ts { } function getConstraintFromIndexedAccess(type: IndexedAccessType) { - const objectType = getConstraintOfType(type.objectType) || type.objectType; - if (objectType !== type.objectType) { - const constraint = getIndexedAccessType(objectType, type.indexType, /*accessNode*/ undefined, errorType); - if (constraint && constraint !== errorType) { - return constraint; + const indexConstraint = getConstraintOfType(type.indexType); + if (indexConstraint && indexConstraint !== type.indexType) { + const indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint); + if (indexedAccess) { + return indexedAccess; } } - const baseConstraint = getBaseConstraintOfType(type); - return baseConstraint && baseConstraint !== type ? baseConstraint : undefined; + const objectConstraint = getConstraintOfType(type.objectType); + if (objectConstraint && objectConstraint !== type.objectType) { + return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType); + } + return undefined; } function getDefaultConstraintOfConditionalType(type: ConditionalType) { @@ -7562,7 +7569,7 @@ namespace ts { // a union - once negated types exist and are applied to the conditional false branch, this "constraint" // likely doesn't need to exist. if (type.root.isDistributive && type.restrictiveInstantiation !== type) { - const simplified = getSimplifiedType(type.checkType); + const simplified = getSimplifiedType(type.checkType, /*writing*/ false); const constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified; if (constraint && constraint !== type.checkType) { const mapper = makeUnaryTypeMapper(type.root.checkType, constraint); @@ -7669,7 +7676,7 @@ namespace ts { return t.immediateBaseConstraint = noConstraintType; } constraintDepth++; - let result = computeBaseConstraint(getSimplifiedType(t)); + let result = computeBaseConstraint(getSimplifiedType(t, /*writing*/ false)); constraintDepth--; if (!popTypeResolution()) { if (t.flags & TypeFlags.TypeParameter) { @@ -7722,8 +7729,8 @@ namespace ts { if (t.flags & TypeFlags.IndexedAccess) { const baseObjectType = getBaseConstraint((t).objectType); const baseIndexType = getBaseConstraint((t).indexType); - const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType, /*accessNode*/ undefined, errorType) : undefined; - return baseIndexedAccess && baseIndexedAccess !== errorType ? getBaseConstraint(baseIndexedAccess) : undefined; + const baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType); + return baseIndexedAccess && getBaseConstraint(baseIndexedAccess); } if (t.flags & TypeFlags.Conditional) { const constraint = getConstraintFromConditionalType(t); @@ -9837,16 +9844,16 @@ namespace ts { return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined; } - function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type { - return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly))) : - type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : + function getIndexType(type: Type, stringsOnly = keyofStringsOnly, noIndexSignatures?: boolean): Type { + return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : + type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) : maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : - getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : + getObjectFlags(type) & ObjectFlags.Mapped ? filterType(getConstraintTypeFromMappedType(type), t => !(noIndexSignatures && t.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Number))) : type === wildcardType ? wildcardType : type.flags & TypeFlags.Any ? keyofConstraintType : - stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) : - getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) : - getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : + stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromProperties(type, TypeFlags.StringLiteral) : + !noIndexSignatures && getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, TypeFlags.UniqueESSymbol)]) : + !noIndexSignatures && getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : getLiteralTypeFromProperties(type, TypeFlags.StringOrNumberLiteralOrUnique); } @@ -9918,7 +9925,7 @@ namespace ts { return false; } - function getPropertyTypeForIndexType(objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, cacheSymbol: boolean, missingType: Type) { + function getPropertyTypeForIndexType(originalObjectType: Type, objectType: Type, indexType: Type, accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression | undefined, accessFlags: AccessFlags) { const accessExpression = accessNode && accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode : undefined; const propName = isTypeUsableAsPropertyName(indexType) ? getPropertyNameFromType(indexType) : @@ -9935,13 +9942,12 @@ namespace ts { markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === SyntaxKind.ThisKeyword); if (isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) { error(accessExpression.argumentExpression, Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(prop)); - return missingType; + return undefined; } - if (cacheSymbol) { + if (accessFlags & AccessFlags.CacheSymbol) { getNodeLinks(accessNode!).resolvedSymbol = prop; } } - const propType = getTypeOfSymbol(prop); return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ? getFlowTypeOfReference(accessExpression, propType) : @@ -9966,15 +9972,25 @@ namespace ts { return objectType; } const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || - getIndexInfoOfType(objectType, IndexKind.String) || - undefined; + getIndexInfoOfType(objectType, IndexKind.String); if (indexInfo) { + if (accessFlags & AccessFlags.NoIndexSignatures) { + 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)) { const indexNode = getIndexNodeForAccessExpression(accessNode); error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); + return indexInfo.type; } - else if (accessExpression && indexInfo.isReadonly && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) { - error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); + if (indexInfo.isReadonly && (accessFlags & AccessFlags.Writing || accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression)))) { + if (accessExpression) { + error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); + return indexInfo.type; + } + return undefined; } return indexInfo.type; } @@ -10007,7 +10023,7 @@ namespace ts { } } } - return missingType; + return undefined; } } if (isJSLiteralType(objectType)) { @@ -10028,7 +10044,7 @@ namespace ts { if (isTypeAny(indexType)) { return indexType; } - return missingType; + return undefined; } function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression) { @@ -10049,53 +10065,68 @@ namespace ts { return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Index); } - function getSimplifiedType(type: Type): Type { - return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type) : type; + function getSimplifiedType(type: Type, writing: boolean): Type { + return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type, writing) : type; } - function distributeIndexOverObjectType(objectType: Type, indexType: Type) { - // (T | U)[K] -> T[K] | U[K] - if (objectType.flags & TypeFlags.Union) { - return mapType(objectType, t => getSimplifiedType(getIndexedAccessType(t, indexType))); - } + function distributeIndexOverObjectType(objectType: Type, indexType: Type, writing: boolean) { + // (T | U)[K] -> T[K] | U[K] (reading) + // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & TypeFlags.Intersection) { - return getIntersectionType(map((objectType as IntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType)))); + if (objectType.flags & TypeFlags.UnionOrIntersection) { + const types = map((objectType as UnionOrIntersectionType).types, t => getSimplifiedType(getIndexedAccessType(t, indexType), writing)); + return objectType.flags & TypeFlags.Intersection || writing ? getIntersectionType(types) : getUnionType(types); } } - // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return - // the type itself if no transformation is possible. - function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { - if (type.simplified) { - return type.simplified === circularConstraintType ? type : type.simplified; + function distributeObjectOverIndexType(objectType: Type, indexType: Type, writing: boolean) { + // T[A | B] -> T[A] | T[B] (reading) + // T[A | B] -> T[A] & T[B] (writing) + if (indexType.flags & TypeFlags.Union) { + const types = map((indexType as UnionType).types, t => getSimplifiedType(getIndexedAccessType(objectType, t), writing)); + return writing ? getIntersectionType(types) : getUnionType(types); } - type.simplified = circularConstraintType; + } + + // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return + // the type itself if no transformation is possible. The writing flag indicates that the type is + // the target of an assignment. + function getSimplifiedIndexedAccessType(type: IndexedAccessType, writing: boolean): Type { + const cache = writing ? "simplifiedForWriting" : "simplifiedForReading"; + if (type[cache]) { + return type[cache] === circularConstraintType ? type : type[cache]!; + } + type[cache] = circularConstraintType; // We recursively simplify the object type as it may in turn be an indexed access type. For example, with // '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type. - const objectType = getSimplifiedType(type.objectType); - const indexType = getSimplifiedType(type.indexType); - // T[A | B] -> T[A] | T[B] - if (indexType.flags & TypeFlags.Union) { - return type.simplified = mapType(indexType, t => getSimplifiedType(getIndexedAccessType(objectType, t))); + const objectType = getSimplifiedType(type.objectType, writing); + const indexType = getSimplifiedType(type.indexType, writing); + // T[A | B] -> T[A] | T[B] (reading) + // T[A | B] -> T[A] & T[B] (writing) + const distributedOverIndex = distributeObjectOverIndexType(objectType, indexType, writing); + if (distributedOverIndex) { + return type[cache] = distributedOverIndex; } // Only do the inner distributions if the index can no longer be instantiated to cause index distribution again if (!(indexType.flags & TypeFlags.Instantiable)) { - const simplified = distributeIndexOverObjectType(objectType, indexType); - if (simplified) { - return type.simplified = simplified; + // (T | U)[K] -> T[K] | U[K] (reading) + // (T | U)[K] -> T[K] & U[K] (writing) + // (T & U)[K] -> T[K] & U[K] + const distributedOverObject = distributeIndexOverObjectType(objectType, indexType, writing); + if (distributedOverObject) { + return type[cache] = distributedOverObject; } } - // So ultimately: + // So ultimately (reading): // ((A & B) | C)[K1 | K2] -> ((A & B) | C)[K1] | ((A & B) | C)[K2] -> (A & B)[K1] | C[K1] | (A & B)[K2] | C[K2] -> (A[K1] & B[K1]) | C[K1] | (A[K2] & B[K2]) | C[K2] // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we // construct the type Box. if (isGenericMappedType(objectType)) { - return type.simplified = mapType(substituteIndexedMappedType(objectType, type.indexType), getSimplifiedType); + return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing)); } - return type.simplified = type; + return type[cache] = type; } function substituteIndexedMappedType(objectType: MappedType, index: Type) { @@ -10104,10 +10135,19 @@ namespace ts { return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); } - function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, missingType = accessNode ? errorType : unknownType): Type { + function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression): Type { + return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, AccessFlags.None) || (accessNode ? errorType : unknownType); + } + + function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, accessFlags = AccessFlags.None): Type | undefined { if (objectType === wildcardType || indexType === wildcardType) { return wildcardType; } + // If the object type has a string index signature and no other members we know that the result will + // always be the type of that index signature and we can simplify accordingly. + if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { + indexType = stringType; + } // If the index type is generic, or if the object type is generic and doesn't originate in an expression, // we are performing a higher-order index access where we cannot meaningfully access the properties of the // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in @@ -10133,25 +10173,25 @@ namespace ts { const propTypes: Type[] = []; let wasMissingProp = false; for (const t of (indexType).types) { - const propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false, missingType); - if (propType === missingType) { - if (!accessNode) { - // If there's no error node, we can immeditely stop, since error reporting is off - return missingType; - } - else { - // Otherwise we set a flag and return at the end of the loop so we still mark all errors - wasMissingProp = true; - } + const propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, accessNode, accessFlags); + if (propType) { + propTypes.push(propType); + } + else if (!accessNode) { + // If there's no error node, we can immeditely stop, since error reporting is off + return undefined; + } + else { + // Otherwise we set a flag and return at the end of the loop so we still mark all errors + wasMissingProp = true; } - propTypes.push(propType); } if (wasMissingProp) { - return missingType; + return undefined; } - return getUnionType(propTypes); + return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes) : getUnionType(propTypes); } - return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true, missingType); + return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, accessNode, accessFlags | AccessFlags.CacheSymbol); } function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) { @@ -11540,10 +11580,10 @@ namespace ts { let reportedError = false; for (let status = iterator.next(); !status.done; status = iterator.next()) { const { errorNode: prop, innerExpression: next, nameType, errorMessage } = status.value; - const targetPropType = getIndexedAccessType(target, nameType, /*accessNode*/ undefined, errorType); - if (targetPropType === errorType || targetPropType.flags & TypeFlags.IndexedAccess) continue; // Don't elaborate on indexes on generic variables - const sourcePropType = getIndexedAccessType(source, nameType, /*accessNode*/ undefined, errorType); - if (sourcePropType !== errorType && targetPropType !== errorType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) { + const targetPropType = getIndexedAccessTypeOrUndefined(target, nameType); + if (!targetPropType || targetPropType.flags & TypeFlags.IndexedAccess) continue; // Don't elaborate on indexes on generic variables + const sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType); + if (sourcePropType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) { const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined); if (elaborated) { reportedError = true; @@ -11985,6 +12025,12 @@ namespace ts { return !!(getObjectFlags(type) & ObjectFlags.Anonymous) && isEmptyObjectType(type); } + function isStringIndexSignatureOnlyType(type: Type): boolean { + return type.flags & TypeFlags.Object && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, IndexKind.String) && !getIndexInfoOfType(type, IndexKind.Number) || + type.flags & TypeFlags.UnionOrIntersection && every((type).types, isStringIndexSignatureOnlyType) || + false; + } + function isEnumTypeRelatedTo(sourceSymbol: Symbol, targetSymbol: Symbol, errorReporter?: ErrorReporter) { if (sourceSymbol === targetSymbol) { return true; @@ -12243,10 +12289,10 @@ namespace ts { target = (target).typeVariable; } if (source.flags & TypeFlags.IndexedAccess) { - source = getSimplifiedType(source); + source = getSimplifiedType(source, /*writing*/ false); } if (target.flags & TypeFlags.IndexedAccess) { - target = getSimplifiedType(target); + target = getSimplifiedType(target, /*writing*/ true); } // Try to see if we're relating something like `Foo` -> `Bar | null | undefined`. @@ -12826,7 +12872,7 @@ namespace ts { } // A type S is assignable to keyof T if S is assignable to keyof C, where C is the // simplified form of T or, if T doesn't simplify, the constraint of T. - const simplified = getSimplifiedType((target).type); + const simplified = getSimplifiedType((target).type, /*writing*/ false); const constraint = simplified !== (target).type ? simplified : getConstraintOfType((target).type); if (constraint) { // We require Ternary.True here such that circular constraints don't cause @@ -12839,13 +12885,17 @@ namespace ts { } } else if (target.flags & TypeFlags.IndexedAccess) { - // A type S is related to a type T[K], where T and K aren't both type variables, if S is related to C, - // where C is the base constraint of T[K] - if (relation !== identityRelation && - !(isGenericObjectType((target).objectType) && isGenericIndexType((target).indexType))) { - const constraint = getBaseConstraintOfType(target); - if (constraint && constraint !== target) { - if (result = isRelatedTo(source, constraint, reportErrors)) { + // A type S is related to a type T[K] if S is related to C, where C is the base + // constraint of T[K] for writing. + if (relation !== identityRelation) { + const objectType = (target).objectType; + const indexType = (target).indexType; + const baseObjectType = getBaseConstraintOfType(objectType) || objectType; + const baseIndexType = getBaseConstraintOfType(indexType) || indexType; + if (!isGenericObjectType(baseObjectType) && !isGenericIndexType(baseIndexType)) { + const accessFlags = AccessFlags.Writing | (baseObjectType !== objectType ? AccessFlags.NoIndexSignatures : 0); + const constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, /*accessNode*/ undefined, accessFlags); + if (constraint && (result = isRelatedTo(source, constraint, reportErrors))) { return result; } } @@ -12862,7 +12912,7 @@ namespace ts { } if (!isGenericMappedType(source)) { const targetConstraint = getConstraintTypeFromMappedType(target); - const sourceKeys = getIndexType(source); + const sourceKeys = getIndexType(source, /*stringsOnly*/ undefined, /*noIndexSignatures*/ true); const hasOptionalUnionKeys = modifiers & MappedTypeModifiers.IncludeOptional && targetConstraint.flags & TypeFlags.Union; const filteredByApplicability = hasOptionalUnionKeys ? filterType(targetConstraint, t => !!isRelatedTo(t, sourceKeys)) : undefined; // A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X. @@ -12894,23 +12944,25 @@ namespace ts { return result; } } - const constraint = getConstraintOfType(source); - if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { - // A type variable with no constraint is not related to the non-primitive object type. - if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { + else { + const constraint = getConstraintOfType(source); + if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) { + // A type variable with no constraint is not related to the non-primitive object type. + if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) { + errorInfo = saveErrorInfo; + return result; + } + } + // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed + else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) { errorInfo = saveErrorInfo; return result; } - } - // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed - else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, isIntersectionConstituent)) { + // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example + else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { errorInfo = saveErrorInfo; return result; - } - // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example - else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, isIntersectionConstituent)) { - errorInfo = saveErrorInfo; - return result; + } } } else if (source.flags & TypeFlags.Index) { @@ -14706,16 +14758,16 @@ namespace ts { } else { // Infer to the simplified version of an indexed access, if possible, to (hopefully) expose more bare type parameters to the inference engine - const simplified = getSimplifiedType(target); + const simplified = getSimplifiedType(target, /*writing*/ false); if (simplified !== target) { inferFromTypesOnce(source, simplified); } else if (target.flags & TypeFlags.IndexedAccess) { - const indexType = getSimplifiedType((target as IndexedAccessType).indexType); + const indexType = getSimplifiedType((target as IndexedAccessType).indexType, /*writing*/ false); // Generally simplifications of instantiable indexes are avoided to keep relationship checking correct, however if our target is an access, we can consider // that key of that access to be "instantiated", since we're looking to find the infernce goal in any way we can. if (indexType.flags & TypeFlags.Instantiable) { - const simplified = distributeIndexOverObjectType(getSimplifiedType((target as IndexedAccessType).objectType), indexType); + const simplified = distributeIndexOverObjectType(getSimplifiedType((target as IndexedAccessType).objectType, /*writing*/ false), indexType, /*writing*/ false); if (simplified && simplified !== target) { inferFromTypesOnce(source, simplified); } @@ -15743,24 +15795,19 @@ namespace ts { if (!(type.flags & TypeFlags.Union)) { return mapper(type); } - const types = (type).types; - let mappedType: Type | undefined; let mappedTypes: Type[] | undefined; - for (const current of types) { - const t = mapper(current); - if (t) { - if (!mappedType) { - mappedType = t; - } - else if (!mappedTypes) { - mappedTypes = [mappedType, t]; + for (const t of (type).types) { + const mapped = mapper(t); + if (mapped) { + if (!mappedTypes) { + mappedTypes = [mapped]; } else { - mappedTypes.push(t); + mappedTypes.push(mapped); } } } - return mappedTypes ? getUnionType(mappedTypes, noReductions ? UnionReduction.None : UnionReduction.Literal) : mappedType; + return mappedTypes && getUnionType(mappedTypes, noReductions ? UnionReduction.None : UnionReduction.Literal); } function extractTypesOfKind(type: Type, kind: TypeFlags) { @@ -19597,7 +19644,7 @@ namespace ts { markAliasReferenced(parentSymbol, node); } if (!prop) { - const indexInfo = getIndexInfoOfType(apparentType, IndexKind.String); + const indexInfo = assignmentKind === AssignmentKind.None || !isGenericObjectType(leftType) ? getIndexInfoOfType(apparentType, IndexKind.String) : undefined; if (!(indexInfo && indexInfo.type)) { if (isJSLiteralType(leftType)) { return anyType; @@ -20002,7 +20049,12 @@ namespace ts { return errorType; } - return checkIndexedAccessIndexType(getIndexedAccessType(objectType, isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType, node), node); + const effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType; + const accessFlags = isAssignmentTarget(node) ? + AccessFlags.Writing | (isGenericObjectType(objectType) ? AccessFlags.NoIndexSignatures : 0) : + AccessFlags.None; + const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType; + return checkIndexedAccessIndexType(indexedAccessType, node); } function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean { @@ -24597,7 +24649,7 @@ namespace ts { return type; } error(accessNode, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType)); - return type; + return errorType; } function checkIndexedAccessType(node: IndexedAccessTypeNode) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 2757c15c5241d..4c68de60c85ed 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -7784,7 +7784,7 @@ namespace ts { const referencedFiles = context.referencedFiles; const typeReferenceDirectives = context.typeReferenceDirectives; const libReferenceDirectives = context.libReferenceDirectives; - forEach(toArray(entryOrList), (arg: PragmaPseudoMap["reference"]) => { + forEach(toArray(entryOrList) as PragmaPseudoMap["reference"][], arg => { const { types, lib, path } = arg.arguments; if (arg.arguments["no-default-lib"]) { context.hasNoDefaultLib = true; @@ -7806,8 +7806,8 @@ namespace ts { } case "amd-dependency": { context.amdDependencies = map( - toArray(entryOrList), - (x: PragmaPseudoMap["amd-dependency"]) => ({ name: x.arguments.name, path: x.arguments.path })); + toArray(entryOrList) as PragmaPseudoMap["amd-dependency"][], + x => ({ name: x.arguments.name, path: x.arguments.path })); break; } case "amd-module": { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 55492081050a8..c47d1657df73e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4279,7 +4279,8 @@ namespace ts { objectType: Type; indexType: Type; constraint?: Type; - simplified?: Type; + simplifiedForReading?: Type; + simplifiedForWriting?: Type; } export type TypeVariable = TypeParameter | IndexedAccessType; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 46cd79bf77dfc..e055f5b802db5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2359,7 +2359,8 @@ declare namespace ts { objectType: Type; indexType: Type; constraint?: Type; - simplified?: Type; + simplifiedForReading?: Type; + simplifiedForWriting?: Type; } type TypeVariable = TypeParameter | IndexedAccessType; interface IndexType extends InstantiableType { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 51c10fdf1956e..d2fd98185b91b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2359,7 +2359,8 @@ declare namespace ts { objectType: Type; indexType: Type; constraint?: Type; - simplified?: Type; + simplifiedForReading?: Type; + simplifiedForWriting?: Type; } type TypeVariable = TypeParameter | IndexedAccessType; interface IndexType extends InstantiableType { diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt index 69ea8e1afd245..04a88a4b1e5ce 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -11,31 +11,22 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] | GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] | GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]) | GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string] | GetProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | (TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. ==== tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== @@ -116,29 +107,20 @@ tests/cases/compiler/circularlyConstrainedMappedTypeContainingConditionalNoInfin !!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. !!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. !!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] | GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] | GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]) | GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string] | GetProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. \ No newline at end of file diff --git a/tests/baselines/reference/infiniteConstraints.errors.txt b/tests/baselines/reference/infiniteConstraints.errors.txt index 414fa8f9213a4..a49aa5e366b58 100644 --- a/tests/baselines/reference/infiniteConstraints.errors.txt +++ b/tests/baselines/reference/infiniteConstraints.errors.txt @@ -1,4 +1,3 @@ -tests/cases/compiler/infiniteConstraints.ts(3,37): error TS2589: Type instantiation is excessively deep and possibly infinite. tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude]'. tests/cases/compiler/infiniteConstraints.ts(21,21): error TS2536: Type '"val"' cannot be used to index type 'Extract>'. tests/cases/compiler/infiniteConstraints.ts(21,57): error TS2536: Type '"val"' cannot be used to index type 'Extract], Record<"val", string>>'. @@ -7,12 +6,10 @@ tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Record<" tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'. -==== tests/cases/compiler/infiniteConstraints.ts (7 errors) ==== +==== tests/cases/compiler/infiniteConstraints.ts (6 errors) ==== // Both of the following types trigger the recursion limiter in getImmediateBaseConstraint type T1], { val: string }>["val"] }> = B; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2589: Type instantiation is excessively deep and possibly infinite. type T2]["val"] }> = B; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2536: Type '"val"' cannot be used to index type 'B[Exclude]'. diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index e30aa81a79092..48bd7b02d2bb6 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1794,7 +1794,7 @@ function updateIds2( >key : K stringMap[x]; // Should be OK. ->stringMap[x] : { [oldId: string]: string; }[T[K]] +>stringMap[x] : string >stringMap : { [oldId: string]: string; } >x : T[K] } diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt new file mode 100644 index 0000000000000..6e1b87a72e38d --- /dev/null +++ b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt @@ -0,0 +1,190 @@ +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(4,5): error TS2322: Type '"x"' is not assignable to type 'number'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(6,5): error TS2322: Type '2' is not assignable to type '0 | 1'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(7,5): error TS2322: Type '"x"' is not assignable to type '0 | 1'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(8,5): error TS2322: Type '1' is not assignable to type 'never'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(9,5): error TS2322: Type '2' is not assignable to type 'never'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(10,5): error TS2322: Type '"x"' is not assignable to type 'never'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(14,5): error TS2739: Type '{ [key: string]: number; }' is missing the following properties from type '{ x: number; y: number; }': x, y +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(15,5): error TS2322: Type 'T' is not assignable to type '{ x: number; y: number; }'. + Type '{ [key: string]: number; }' is missing the following properties from type '{ x: number; y: number; }': x, y +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(18,5): error TS2322: Type '{ x: number; y: number; }' is not assignable to type 'T'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(19,5): error TS2322: Type '{ [key: string]: number; }' is not assignable to type 'T'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(26,7): error TS2339: Property 'x' does not exist on type 'T'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(27,5): error TS2322: Type '1' is not assignable to type 'T[keyof T]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(31,5): error TS2322: Type '{ [key: string]: number; }' is not assignable to type '{ [P in K]: number; }'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(38,5): error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ [P in K]: number; }'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(50,3): error TS7017: Element implicitly has an 'any' type because type 'Item' has no index signature. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(51,3): error TS2322: Type '123' is not assignable to type 'string & number'. + Type '123' is not assignable to type 'string'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(52,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(53,3): error TS2322: Type '123' is not assignable to type 'T[K]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(65,7): error TS2339: Property 'foo' does not exist on type 'T'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(66,3): error TS2536: Type 'string' cannot be used to index type 'T'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(67,3): error TS2322: Type '123' is not assignable to type 'T[keyof T]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(68,3): error TS2322: Type '123' is not assignable to type 'T[K]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS2322: Type '123' is not assignable to type 'Type[K]'. + Type '123' is not assignable to type '123 & "some string"'. + Type '123' is not assignable to type '"some string"'. + + +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts (23 errors) ==== + function f1(obj: { a: number, b: 0 | 1, c: string }, k0: 'a', k1: 'a' | 'b', k2: 'a' | 'b' | 'c') { + obj[k0] = 1; + obj[k0] = 2; + obj[k0] = 'x'; // Error + ~~~~~~~ +!!! error TS2322: Type '"x"' is not assignable to type 'number'. + obj[k1] = 1; + obj[k1] = 2; // Error + ~~~~~~~ +!!! error TS2322: Type '2' is not assignable to type '0 | 1'. + obj[k1] = 'x'; // Error + ~~~~~~~ +!!! error TS2322: Type '"x"' is not assignable to type '0 | 1'. + obj[k2] = 1; // Error + ~~~~~~~ +!!! error TS2322: Type '1' is not assignable to type 'never'. + obj[k2] = 2; // Error + ~~~~~~~ +!!! error TS2322: Type '2' is not assignable to type 'never'. + obj[k2] = 'x'; // Error + ~~~~~~~ +!!! error TS2322: Type '"x"' is not assignable to type 'never'. + } + + function f2(a: { x: number, y: number }, b: { [key: string]: number }, c: T, k: keyof T) { + a = b; // Error, index signature in source doesn't imply properties are present + ~ +!!! error TS2739: Type '{ [key: string]: number; }' is missing the following properties from type '{ x: number; y: number; }': x, y + a = c; // Error, index signature in source doesn't imply properties are present + ~ +!!! error TS2322: Type 'T' is not assignable to type '{ x: number; y: number; }'. +!!! error TS2322: Type '{ [key: string]: number; }' is missing the following properties from type '{ x: number; y: number; }': x, y + b = a; + b = c; + c = a; // Error, constraint on target doesn't imply any properties or signatures + ~ +!!! error TS2322: Type '{ x: number; y: number; }' is not assignable to type 'T'. + c = b; // Error, constraint on target doesn't imply any properties or signatures + ~ +!!! error TS2322: Type '{ [key: string]: number; }' is not assignable to type 'T'. + a.x; + b.x; + c.x; + c[k]; + a.x = 1; + b.x = 1; + c.x = 1; // Error, cannot write to index signature through constraint + ~ +!!! error TS2339: Property 'x' does not exist on type 'T'. + c[k] = 1; // Error, cannot write to index signature through constraint + ~~~~ +!!! error TS2322: Type '1' is not assignable to type 'T[keyof T]'. + } + + function f3(a: { [P in K]: number }, b: { [key: string]: number }, k: K) { + a = b; // Error, index signature doesn't imply properties are present + ~ +!!! error TS2322: Type '{ [key: string]: number; }' is not assignable to type '{ [P in K]: number; }'. + b = a; + a[k]; + a[k] = 1; + } + + function f3b(a: { [P in K]: number }, b: { [P in string]: number }, k: K) { + a = b; // Error, index signature doesn't imply properties are present + ~ +!!! error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ [P in K]: number; }'. + b = a; + } + + function f4(a: { [key: string]: number }[K], b: number) { + a = b; + b = a; + } + + type Item = { a: string, b: number }; + + function f10(obj: T, k1: string, k2: keyof Item, k3: keyof T, k4: K) { + obj[k1] = 123; // Error + ~~~~~~~ +!!! error TS7017: Element implicitly has an 'any' type because type 'Item' has no index signature. + obj[k2] = 123; // Error + ~~~~~~~ +!!! error TS2322: Type '123' is not assignable to type 'string & number'. +!!! error TS2322: Type '123' is not assignable to type 'string'. + obj[k3] = 123; // Error + ~~~~~~~ +!!! error TS2322: Type '123' is not assignable to type 'T[keyof T]'. + obj[k4] = 123; // Error + ~~~~~~~ +!!! error TS2322: Type '123' is not assignable to type 'T[K]'. + } + + type Dict = Record; + + function f11(obj: Dict, k1: keyof Dict, k2: K) { + obj.foo = 123; + obj[k1] = 123; + obj[k2] = 123; + } + + function f12, K extends keyof T>(obj: T, k1: keyof Dict, k2: keyof T, k3: K) { + obj.foo = 123; // Error + ~~~ +!!! error TS2339: Property 'foo' does not exist on type 'T'. + obj[k1] = 123; // Error + ~~~~~~~ +!!! error TS2536: Type 'string' cannot be used to index type 'T'. + obj[k2] = 123; // Error + ~~~~~~~ +!!! error TS2322: Type '123' is not assignable to type 'T[keyof T]'. + obj[k3] = 123; // Error + ~~~~~~~ +!!! error TS2322: Type '123' is not assignable to type 'T[K]'. + } + + // Repro from #27895 + + export interface Entity { + id: number | string; + } + + export type IdOf = E['id']; + + export interface EntityState { + ids: IdOf[]; + entities: { [key: string]: E, [key: number]: E }; + } + + + export function getAllEntities(state: EntityState): E[] { + const { ids, entities } = state; + return ids.map(id => entities[id]); + } + + export function getEntity(id: IdOf, state: EntityState): E | undefined { + const { ids, entities } = state; + + if (!ids.includes(id)) { + return undefined; + } + + return entities[id]; + } + + // Repro from #30603 + + interface Type { + a: 123; + b: "some string"; + } + + function get123(): Type[K] { + return 123; // Error + ~~~~~~~~~~~ +!!! error TS2322: Type '123' is not assignable to type 'Type[K]'. +!!! error TS2322: Type '123' is not assignable to type '123 & "some string"'. +!!! error TS2322: Type '123' is not assignable to type '"some string"'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.js b/tests/baselines/reference/keyofAndIndexedAccess2.js new file mode 100644 index 0000000000000..8dad708c2988c --- /dev/null +++ b/tests/baselines/reference/keyofAndIndexedAccess2.js @@ -0,0 +1,185 @@ +//// [keyofAndIndexedAccess2.ts] +function f1(obj: { a: number, b: 0 | 1, c: string }, k0: 'a', k1: 'a' | 'b', k2: 'a' | 'b' | 'c') { + obj[k0] = 1; + obj[k0] = 2; + obj[k0] = 'x'; // Error + obj[k1] = 1; + obj[k1] = 2; // Error + obj[k1] = 'x'; // Error + obj[k2] = 1; // Error + obj[k2] = 2; // Error + obj[k2] = 'x'; // Error +} + +function f2(a: { x: number, y: number }, b: { [key: string]: number }, c: T, k: keyof T) { + a = b; // Error, index signature in source doesn't imply properties are present + a = c; // Error, index signature in source doesn't imply properties are present + b = a; + b = c; + c = a; // Error, constraint on target doesn't imply any properties or signatures + c = b; // Error, constraint on target doesn't imply any properties or signatures + a.x; + b.x; + c.x; + c[k]; + a.x = 1; + b.x = 1; + c.x = 1; // Error, cannot write to index signature through constraint + c[k] = 1; // Error, cannot write to index signature through constraint +} + +function f3(a: { [P in K]: number }, b: { [key: string]: number }, k: K) { + a = b; // Error, index signature doesn't imply properties are present + b = a; + a[k]; + a[k] = 1; +} + +function f3b(a: { [P in K]: number }, b: { [P in string]: number }, k: K) { + a = b; // Error, index signature doesn't imply properties are present + b = a; +} + +function f4(a: { [key: string]: number }[K], b: number) { + a = b; + b = a; +} + +type Item = { a: string, b: number }; + +function f10(obj: T, k1: string, k2: keyof Item, k3: keyof T, k4: K) { + obj[k1] = 123; // Error + obj[k2] = 123; // Error + obj[k3] = 123; // Error + obj[k4] = 123; // Error +} + +type Dict = Record; + +function f11(obj: Dict, k1: keyof Dict, k2: K) { + obj.foo = 123; + obj[k1] = 123; + obj[k2] = 123; +} + +function f12, K extends keyof T>(obj: T, k1: keyof Dict, k2: keyof T, k3: K) { + obj.foo = 123; // Error + obj[k1] = 123; // Error + obj[k2] = 123; // Error + obj[k3] = 123; // Error +} + +// Repro from #27895 + +export interface Entity { + id: number | string; +} + +export type IdOf = E['id']; + +export interface EntityState { + ids: IdOf[]; + entities: { [key: string]: E, [key: number]: E }; +} + + +export function getAllEntities(state: EntityState): E[] { + const { ids, entities } = state; + return ids.map(id => entities[id]); +} + +export function getEntity(id: IdOf, state: EntityState): E | undefined { + const { ids, entities } = state; + + if (!ids.includes(id)) { + return undefined; + } + + return entities[id]; +} + +// Repro from #30603 + +interface Type { + a: 123; + b: "some string"; +} + +function get123(): Type[K] { + return 123; // Error +} + + +//// [keyofAndIndexedAccess2.js] +function f1(obj, k0, k1, k2) { + obj[k0] = 1; + obj[k0] = 2; + obj[k0] = 'x'; // Error + obj[k1] = 1; + obj[k1] = 2; // Error + obj[k1] = 'x'; // Error + obj[k2] = 1; // Error + obj[k2] = 2; // Error + obj[k2] = 'x'; // Error +} +function f2(a, b, c, k) { + a = b; // Error, index signature in source doesn't imply properties are present + a = c; // Error, index signature in source doesn't imply properties are present + b = a; + b = c; + c = a; // Error, constraint on target doesn't imply any properties or signatures + c = b; // Error, constraint on target doesn't imply any properties or signatures + a.x; + b.x; + c.x; + c[k]; + a.x = 1; + b.x = 1; + c.x = 1; // Error, cannot write to index signature through constraint + c[k] = 1; // Error, cannot write to index signature through constraint +} +function f3(a, b, k) { + a = b; // Error, index signature doesn't imply properties are present + b = a; + a[k]; + a[k] = 1; +} +function f3b(a, b, k) { + a = b; // Error, index signature doesn't imply properties are present + b = a; +} +function f4(a, b) { + a = b; + b = a; +} +function f10(obj, k1, k2, k3, k4) { + obj[k1] = 123; // Error + obj[k2] = 123; // Error + obj[k3] = 123; // Error + obj[k4] = 123; // Error +} +function f11(obj, k1, k2) { + obj.foo = 123; + obj[k1] = 123; + obj[k2] = 123; +} +function f12(obj, k1, k2, k3) { + obj.foo = 123; // Error + obj[k1] = 123; // Error + obj[k2] = 123; // Error + obj[k3] = 123; // Error +} +export function getAllEntities(state) { + const { ids, entities } = state; + return ids.map(id => entities[id]); +} +export function getEntity(id, state) { + const { ids, entities } = state; + if (!ids.includes(id)) { + return undefined; + } + return entities[id]; +} +function get123() { + return 123; // Error +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.symbols b/tests/baselines/reference/keyofAndIndexedAccess2.symbols new file mode 100644 index 0000000000000..803700efa372a --- /dev/null +++ b/tests/baselines/reference/keyofAndIndexedAccess2.symbols @@ -0,0 +1,390 @@ +=== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts === +function f1(obj: { a: number, b: 0 | 1, c: string }, k0: 'a', k1: 'a' | 'b', k2: 'a' | 'b' | 'c') { +>f1 : Symbol(f1, Decl(keyofAndIndexedAccess2.ts, 0, 0)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 0, 18)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 0, 29)) +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 0, 39)) +>k0 : Symbol(k0, Decl(keyofAndIndexedAccess2.ts, 0, 52)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 0, 61)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 0, 76)) + + obj[k0] = 1; +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k0 : Symbol(k0, Decl(keyofAndIndexedAccess2.ts, 0, 52)) + + obj[k0] = 2; +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k0 : Symbol(k0, Decl(keyofAndIndexedAccess2.ts, 0, 52)) + + obj[k0] = 'x'; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k0 : Symbol(k0, Decl(keyofAndIndexedAccess2.ts, 0, 52)) + + obj[k1] = 1; +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 0, 61)) + + obj[k1] = 2; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 0, 61)) + + obj[k1] = 'x'; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 0, 61)) + + obj[k2] = 1; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 0, 76)) + + obj[k2] = 2; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 0, 76)) + + obj[k2] = 'x'; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 0, 12)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 0, 76)) +} + +function f2(a: { x: number, y: number }, b: { [key: string]: number }, c: T, k: keyof T) { +>f2 : Symbol(f2, Decl(keyofAndIndexedAccess2.ts, 10, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 12, 12)) +>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 12, 25)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) +>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53)) +>y : Symbol(y, Decl(keyofAndIndexedAccess2.ts, 12, 64)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) +>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 12, 84)) +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 12, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 12, 113)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 12, 12)) + + a = b; // Error, index signature in source doesn't imply properties are present +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) + + a = c; // Error, index signature in source doesn't imply properties are present +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) + + b = a; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) + + b = c; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) + + c = a; // Error, constraint on target doesn't imply any properties or signatures +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) + + c = b; // Error, constraint on target doesn't imply any properties or signatures +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) + + a.x; +>a.x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) +>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53)) + + b.x; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) + + c.x; +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) + + c[k]; +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 12, 113)) + + a.x = 1; +>a.x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 12, 49)) +>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 12, 53)) + + b.x = 1; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 12, 77)) + + c.x = 1; // Error, cannot write to index signature through constraint +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) + + c[k] = 1; // Error, cannot write to index signature through constraint +>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 12, 107)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 12, 113)) +} + +function f3(a: { [P in K]: number }, b: { [key: string]: number }, k: K) { +>f3 : Symbol(f3, Decl(keyofAndIndexedAccess2.ts, 27, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 29, 12)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 29, 30)) +>P : Symbol(P, Decl(keyofAndIndexedAccess2.ts, 29, 36)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 29, 12)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 29, 54)) +>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 29, 61)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 29, 84)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 29, 12)) + + a = b; // Error, index signature doesn't imply properties are present +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 29, 30)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 29, 54)) + + b = a; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 29, 54)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 29, 30)) + + a[k]; +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 29, 30)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 29, 84)) + + a[k] = 1; +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 29, 30)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 29, 84)) +} + +function f3b(a: { [P in K]: number }, b: { [P in string]: number }, k: K) { +>f3b : Symbol(f3b, Decl(keyofAndIndexedAccess2.ts, 34, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 36, 13)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 36, 31)) +>P : Symbol(P, Decl(keyofAndIndexedAccess2.ts, 36, 37)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 36, 13)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 36, 55)) +>P : Symbol(P, Decl(keyofAndIndexedAccess2.ts, 36, 62)) +>k : Symbol(k, Decl(keyofAndIndexedAccess2.ts, 36, 85)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 36, 13)) + + a = b; // Error, index signature doesn't imply properties are present +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 36, 31)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 36, 55)) + + b = a; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 36, 55)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 36, 31)) +} + +function f4(a: { [key: string]: number }[K], b: number) { +>f4 : Symbol(f4, Decl(keyofAndIndexedAccess2.ts, 39, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 41, 12)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 41, 30)) +>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 41, 36)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 41, 12)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 41, 62)) + + a = b; +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 41, 30)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 41, 62)) + + b = a; +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 41, 62)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 41, 30)) +} + +type Item = { a: string, b: number }; +>Item : Symbol(Item, Decl(keyofAndIndexedAccess2.ts, 44, 1)) +>a : Symbol(a, Decl(keyofAndIndexedAccess2.ts, 46, 13)) +>b : Symbol(b, Decl(keyofAndIndexedAccess2.ts, 46, 24)) + +function f10(obj: T, k1: string, k2: keyof Item, k3: keyof T, k4: K) { +>f10 : Symbol(f10, Decl(keyofAndIndexedAccess2.ts, 46, 37)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 48, 13)) +>Item : Symbol(Item, Decl(keyofAndIndexedAccess2.ts, 44, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 48, 28)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 48, 13)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 48, 48)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 48, 13)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 48, 55)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 48, 67)) +>Item : Symbol(Item, Decl(keyofAndIndexedAccess2.ts, 44, 1)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccess2.ts, 48, 83)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 48, 13)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccess2.ts, 48, 96)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 48, 28)) + + obj[k1] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 48, 48)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 48, 55)) + + obj[k2] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 48, 48)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 48, 67)) + + obj[k3] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 48, 48)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccess2.ts, 48, 83)) + + obj[k4] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 48, 48)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccess2.ts, 48, 96)) +} + +type Dict = Record; +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess2.ts, 53, 1)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +function f11(obj: Dict, k1: keyof Dict, k2: K) { +>f11 : Symbol(f11, Decl(keyofAndIndexedAccess2.ts, 55, 35)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 57, 13)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess2.ts, 53, 1)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 57, 35)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess2.ts, 53, 1)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 57, 45)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess2.ts, 53, 1)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 57, 61)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 57, 13)) + + obj.foo = 123; +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 57, 35)) + + obj[k1] = 123; +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 57, 35)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 57, 45)) + + obj[k2] = 123; +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 57, 35)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 57, 61)) +} + +function f12, K extends keyof T>(obj: T, k1: keyof Dict, k2: keyof T, k3: K) { +>f12 : Symbol(f12, Decl(keyofAndIndexedAccess2.ts, 61, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 63, 13)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess2.ts, 53, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 63, 38)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 63, 13)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 63, 58)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 63, 13)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 63, 65)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess2.ts, 53, 1)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 63, 81)) +>T : Symbol(T, Decl(keyofAndIndexedAccess2.ts, 63, 13)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccess2.ts, 63, 94)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 63, 38)) + + obj.foo = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 63, 58)) + + obj[k1] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 63, 58)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess2.ts, 63, 65)) + + obj[k2] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 63, 58)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess2.ts, 63, 81)) + + obj[k3] = 123; // Error +>obj : Symbol(obj, Decl(keyofAndIndexedAccess2.ts, 63, 58)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccess2.ts, 63, 94)) +} + +// Repro from #27895 + +export interface Entity { +>Entity : Symbol(Entity, Decl(keyofAndIndexedAccess2.ts, 68, 1)) + + id: number | string; +>id : Symbol(Entity.id, Decl(keyofAndIndexedAccess2.ts, 72, 25)) +} + +export type IdOf = E['id']; +>IdOf : Symbol(IdOf, Decl(keyofAndIndexedAccess2.ts, 74, 1)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 76, 17)) +>Entity : Symbol(Entity, Decl(keyofAndIndexedAccess2.ts, 68, 1)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 76, 17)) + +export interface EntityState { +>EntityState : Symbol(EntityState, Decl(keyofAndIndexedAccess2.ts, 76, 45)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 78, 29)) +>Entity : Symbol(Entity, Decl(keyofAndIndexedAccess2.ts, 68, 1)) + + ids: IdOf[]; +>ids : Symbol(EntityState.ids, Decl(keyofAndIndexedAccess2.ts, 78, 48)) +>IdOf : Symbol(IdOf, Decl(keyofAndIndexedAccess2.ts, 74, 1)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 78, 29)) + + entities: { [key: string]: E, [key: number]: E }; +>entities : Symbol(EntityState.entities, Decl(keyofAndIndexedAccess2.ts, 79, 19)) +>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 80, 17)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 78, 29)) +>key : Symbol(key, Decl(keyofAndIndexedAccess2.ts, 80, 35)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 78, 29)) +} + + +export function getAllEntities(state: EntityState): E[] { +>getAllEntities : Symbol(getAllEntities, Decl(keyofAndIndexedAccess2.ts, 81, 1)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 84, 31)) +>Entity : Symbol(Entity, Decl(keyofAndIndexedAccess2.ts, 68, 1)) +>state : Symbol(state, Decl(keyofAndIndexedAccess2.ts, 84, 49)) +>EntityState : Symbol(EntityState, Decl(keyofAndIndexedAccess2.ts, 76, 45)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 84, 31)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 84, 31)) + + const { ids, entities } = state; +>ids : Symbol(ids, Decl(keyofAndIndexedAccess2.ts, 85, 11)) +>entities : Symbol(entities, Decl(keyofAndIndexedAccess2.ts, 85, 16)) +>state : Symbol(state, Decl(keyofAndIndexedAccess2.ts, 84, 49)) + + return ids.map(id => entities[id]); +>ids.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>ids : Symbol(ids, Decl(keyofAndIndexedAccess2.ts, 85, 11)) +>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) +>id : Symbol(id, Decl(keyofAndIndexedAccess2.ts, 86, 19)) +>entities : Symbol(entities, Decl(keyofAndIndexedAccess2.ts, 85, 16)) +>id : Symbol(id, Decl(keyofAndIndexedAccess2.ts, 86, 19)) +} + +export function getEntity(id: IdOf, state: EntityState): E | undefined { +>getEntity : Symbol(getEntity, Decl(keyofAndIndexedAccess2.ts, 87, 1)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 89, 26)) +>Entity : Symbol(Entity, Decl(keyofAndIndexedAccess2.ts, 68, 1)) +>id : Symbol(id, Decl(keyofAndIndexedAccess2.ts, 89, 44)) +>IdOf : Symbol(IdOf, Decl(keyofAndIndexedAccess2.ts, 74, 1)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 89, 26)) +>state : Symbol(state, Decl(keyofAndIndexedAccess2.ts, 89, 56)) +>EntityState : Symbol(EntityState, Decl(keyofAndIndexedAccess2.ts, 76, 45)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 89, 26)) +>E : Symbol(E, Decl(keyofAndIndexedAccess2.ts, 89, 26)) + + const { ids, entities } = state; +>ids : Symbol(ids, Decl(keyofAndIndexedAccess2.ts, 90, 11)) +>entities : Symbol(entities, Decl(keyofAndIndexedAccess2.ts, 90, 16)) +>state : Symbol(state, Decl(keyofAndIndexedAccess2.ts, 89, 56)) + + if (!ids.includes(id)) { +>ids.includes : Symbol(Array.includes, Decl(lib.es2016.array.include.d.ts, --, --)) +>ids : Symbol(ids, Decl(keyofAndIndexedAccess2.ts, 90, 11)) +>includes : Symbol(Array.includes, Decl(lib.es2016.array.include.d.ts, --, --)) +>id : Symbol(id, Decl(keyofAndIndexedAccess2.ts, 89, 44)) + + return undefined; +>undefined : Symbol(undefined) + } + + return entities[id]; +>entities : Symbol(entities, Decl(keyofAndIndexedAccess2.ts, 90, 16)) +>id : Symbol(id, Decl(keyofAndIndexedAccess2.ts, 89, 44)) +} + +// Repro from #30603 + +interface Type { +>Type : Symbol(Type, Decl(keyofAndIndexedAccess2.ts, 97, 1)) + + a: 123; +>a : Symbol(Type.a, Decl(keyofAndIndexedAccess2.ts, 101, 16)) + + b: "some string"; +>b : Symbol(Type.b, Decl(keyofAndIndexedAccess2.ts, 102, 11)) +} + +function get123(): Type[K] { +>get123 : Symbol(get123, Decl(keyofAndIndexedAccess2.ts, 104, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 106, 16)) +>Type : Symbol(Type, Decl(keyofAndIndexedAccess2.ts, 97, 1)) +>Type : Symbol(Type, Decl(keyofAndIndexedAccess2.ts, 97, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 106, 16)) + + return 123; // Error +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.types b/tests/baselines/reference/keyofAndIndexedAccess2.types new file mode 100644 index 0000000000000..5f5b80a481911 --- /dev/null +++ b/tests/baselines/reference/keyofAndIndexedAccess2.types @@ -0,0 +1,425 @@ +=== tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts === +function f1(obj: { a: number, b: 0 | 1, c: string }, k0: 'a', k1: 'a' | 'b', k2: 'a' | 'b' | 'c') { +>f1 : (obj: { a: number; b: 0 | 1; c: string; }, k0: "a", k1: "a" | "b", k2: "a" | "b" | "c") => void +>obj : { a: number; b: 0 | 1; c: string; } +>a : number +>b : 0 | 1 +>c : string +>k0 : "a" +>k1 : "a" | "b" +>k2 : "a" | "b" | "c" + + obj[k0] = 1; +>obj[k0] = 1 : 1 +>obj[k0] : number +>obj : { a: number; b: 0 | 1; c: string; } +>k0 : "a" +>1 : 1 + + obj[k0] = 2; +>obj[k0] = 2 : 2 +>obj[k0] : number +>obj : { a: number; b: 0 | 1; c: string; } +>k0 : "a" +>2 : 2 + + obj[k0] = 'x'; // Error +>obj[k0] = 'x' : "x" +>obj[k0] : number +>obj : { a: number; b: 0 | 1; c: string; } +>k0 : "a" +>'x' : "x" + + obj[k1] = 1; +>obj[k1] = 1 : 1 +>obj[k1] : 0 | 1 +>obj : { a: number; b: 0 | 1; c: string; } +>k1 : "a" | "b" +>1 : 1 + + obj[k1] = 2; // Error +>obj[k1] = 2 : 2 +>obj[k1] : 0 | 1 +>obj : { a: number; b: 0 | 1; c: string; } +>k1 : "a" | "b" +>2 : 2 + + obj[k1] = 'x'; // Error +>obj[k1] = 'x' : "x" +>obj[k1] : 0 | 1 +>obj : { a: number; b: 0 | 1; c: string; } +>k1 : "a" | "b" +>'x' : "x" + + obj[k2] = 1; // Error +>obj[k2] = 1 : 1 +>obj[k2] : never +>obj : { a: number; b: 0 | 1; c: string; } +>k2 : "a" | "b" | "c" +>1 : 1 + + obj[k2] = 2; // Error +>obj[k2] = 2 : 2 +>obj[k2] : never +>obj : { a: number; b: 0 | 1; c: string; } +>k2 : "a" | "b" | "c" +>2 : 2 + + obj[k2] = 'x'; // Error +>obj[k2] = 'x' : "x" +>obj[k2] : never +>obj : { a: number; b: 0 | 1; c: string; } +>k2 : "a" | "b" | "c" +>'x' : "x" +} + +function f2(a: { x: number, y: number }, b: { [key: string]: number }, c: T, k: keyof T) { +>f2 : (a: { x: number; y: number; }, b: { [key: string]: number; }, c: T, k: keyof T) => void +>key : string +>a : { x: number; y: number; } +>x : number +>y : number +>b : { [key: string]: number; } +>key : string +>c : T +>k : keyof T + + a = b; // Error, index signature in source doesn't imply properties are present +>a = b : { [key: string]: number; } +>a : { x: number; y: number; } +>b : { [key: string]: number; } + + a = c; // Error, index signature in source doesn't imply properties are present +>a = c : T +>a : { x: number; y: number; } +>c : T + + b = a; +>b = a : { x: number; y: number; } +>b : { [key: string]: number; } +>a : { x: number; y: number; } + + b = c; +>b = c : T +>b : { [key: string]: number; } +>c : T + + c = a; // Error, constraint on target doesn't imply any properties or signatures +>c = a : { x: number; y: number; } +>c : T +>a : { x: number; y: number; } + + c = b; // Error, constraint on target doesn't imply any properties or signatures +>c = b : { [key: string]: number; } +>c : T +>b : { [key: string]: number; } + + a.x; +>a.x : number +>a : { x: number; y: number; } +>x : number + + b.x; +>b.x : number +>b : { [key: string]: number; } +>x : number + + c.x; +>c.x : number +>c : T +>x : number + + c[k]; +>c[k] : T[keyof T] +>c : T +>k : keyof T + + a.x = 1; +>a.x = 1 : 1 +>a.x : number +>a : { x: number; y: number; } +>x : number +>1 : 1 + + b.x = 1; +>b.x = 1 : 1 +>b.x : number +>b : { [key: string]: number; } +>x : number +>1 : 1 + + c.x = 1; // Error, cannot write to index signature through constraint +>c.x = 1 : 1 +>c.x : any +>c : T +>x : any +>1 : 1 + + c[k] = 1; // Error, cannot write to index signature through constraint +>c[k] = 1 : 1 +>c[k] : T[keyof T] +>c : T +>k : keyof T +>1 : 1 +} + +function f3(a: { [P in K]: number }, b: { [key: string]: number }, k: K) { +>f3 : (a: { [P in K]: number; }, b: { [key: string]: number; }, k: K) => void +>a : { [P in K]: number; } +>b : { [key: string]: number; } +>key : string +>k : K + + a = b; // Error, index signature doesn't imply properties are present +>a = b : { [key: string]: number; } +>a : { [P in K]: number; } +>b : { [key: string]: number; } + + b = a; +>b = a : { [P in K]: number; } +>b : { [key: string]: number; } +>a : { [P in K]: number; } + + a[k]; +>a[k] : { [P in K]: number; }[K] +>a : { [P in K]: number; } +>k : K + + a[k] = 1; +>a[k] = 1 : 1 +>a[k] : { [P in K]: number; }[K] +>a : { [P in K]: number; } +>k : K +>1 : 1 +} + +function f3b(a: { [P in K]: number }, b: { [P in string]: number }, k: K) { +>f3b : (a: { [P in K]: number; }, b: { [x: string]: number; }, k: K) => void +>a : { [P in K]: number; } +>b : { [x: string]: number; } +>k : K + + a = b; // Error, index signature doesn't imply properties are present +>a = b : { [x: string]: number; } +>a : { [P in K]: number; } +>b : { [x: string]: number; } + + b = a; +>b = a : { [P in K]: number; } +>b : { [x: string]: number; } +>a : { [P in K]: number; } +} + +function f4(a: { [key: string]: number }[K], b: number) { +>f4 : (a: number, b: number) => void +>a : number +>key : string +>b : number + + a = b; +>a = b : number +>a : number +>b : number + + b = a; +>b = a : number +>b : number +>a : number +} + +type Item = { a: string, b: number }; +>Item : Item +>a : string +>b : number + +function f10(obj: T, k1: string, k2: keyof Item, k3: keyof T, k4: K) { +>f10 : (obj: T, k1: string, k2: "a" | "b", k3: keyof T, k4: K) => void +>obj : T +>k1 : string +>k2 : "a" | "b" +>k3 : keyof T +>k4 : K + + obj[k1] = 123; // Error +>obj[k1] = 123 : 123 +>obj[k1] : any +>obj : T +>k1 : string +>123 : 123 + + obj[k2] = 123; // Error +>obj[k2] = 123 : 123 +>obj[k2] : string & number +>obj : T +>k2 : "a" | "b" +>123 : 123 + + obj[k3] = 123; // Error +>obj[k3] = 123 : 123 +>obj[k3] : T[keyof T] +>obj : T +>k3 : keyof T +>123 : 123 + + obj[k4] = 123; // Error +>obj[k4] = 123 : 123 +>obj[k4] : T[K] +>obj : T +>k4 : K +>123 : 123 +} + +type Dict = Record; +>Dict : Record + +function f11(obj: Dict, k1: keyof Dict, k2: K) { +>f11 : (obj: Record, k1: string, k2: K) => void +>obj : Record +>k1 : string +>k2 : K + + obj.foo = 123; +>obj.foo = 123 : 123 +>obj.foo : number +>obj : Record +>foo : number +>123 : 123 + + obj[k1] = 123; +>obj[k1] = 123 : 123 +>obj[k1] : number +>obj : Record +>k1 : string +>123 : 123 + + obj[k2] = 123; +>obj[k2] = 123 : 123 +>obj[k2] : number +>obj : Record +>k2 : K +>123 : 123 +} + +function f12, K extends keyof T>(obj: T, k1: keyof Dict, k2: keyof T, k3: K) { +>f12 : >, K extends keyof T>(obj: T, k1: string, k2: keyof T, k3: K) => void +>obj : T +>k1 : string +>k2 : keyof T +>k3 : K + + obj.foo = 123; // Error +>obj.foo = 123 : 123 +>obj.foo : any +>obj : T +>foo : any +>123 : 123 + + obj[k1] = 123; // Error +>obj[k1] = 123 : 123 +>obj[k1] : any +>obj : T +>k1 : string +>123 : 123 + + obj[k2] = 123; // Error +>obj[k2] = 123 : 123 +>obj[k2] : T[keyof T] +>obj : T +>k2 : keyof T +>123 : 123 + + obj[k3] = 123; // Error +>obj[k3] = 123 : 123 +>obj[k3] : T[K] +>obj : T +>k3 : K +>123 : 123 +} + +// Repro from #27895 + +export interface Entity { + id: number | string; +>id : string | number +} + +export type IdOf = E['id']; +>IdOf : E["id"] + +export interface EntityState { + ids: IdOf[]; +>ids : E["id"][] + + entities: { [key: string]: E, [key: number]: E }; +>entities : { [key: string]: E; [key: number]: E; } +>key : string +>key : number +} + + +export function getAllEntities(state: EntityState): E[] { +>getAllEntities : (state: EntityState) => E[] +>state : EntityState + + const { ids, entities } = state; +>ids : E["id"][] +>entities : { [key: string]: E; [key: number]: E; } +>state : EntityState + + return ids.map(id => entities[id]); +>ids.map(id => entities[id]) : { [key: string]: E; [key: number]: E; }[E["id"]][] +>ids.map : (callbackfn: (value: E["id"], index: number, array: E["id"][]) => U, thisArg?: any) => U[] +>ids : E["id"][] +>map : (callbackfn: (value: E["id"], index: number, array: E["id"][]) => U, thisArg?: any) => U[] +>id => entities[id] : (id: E["id"]) => { [key: string]: E; [key: number]: E; }[E["id"]] +>id : E["id"] +>entities[id] : { [key: string]: E; [key: number]: E; }[E["id"]] +>entities : { [key: string]: E; [key: number]: E; } +>id : E["id"] +} + +export function getEntity(id: IdOf, state: EntityState): E | undefined { +>getEntity : (id: E["id"], state: EntityState) => E | undefined +>id : E["id"] +>state : EntityState + + const { ids, entities } = state; +>ids : E["id"][] +>entities : { [key: string]: E; [key: number]: E; } +>state : EntityState + + if (!ids.includes(id)) { +>!ids.includes(id) : boolean +>ids.includes(id) : boolean +>ids.includes : (searchElement: E["id"], fromIndex?: number | undefined) => boolean +>ids : E["id"][] +>includes : (searchElement: E["id"], fromIndex?: number | undefined) => boolean +>id : E["id"] + + return undefined; +>undefined : undefined + } + + return entities[id]; +>entities[id] : { [key: string]: E; [key: number]: E; }[E["id"]] +>entities : { [key: string]: E; [key: number]: E; } +>id : E["id"] +} + +// Repro from #30603 + +interface Type { + a: 123; +>a : 123 + + b: "some string"; +>b : "some string" +} + +function get123(): Type[K] { +>get123 : () => Type[K] + + return 123; // Error +>123 : 123 +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 90df0e687a057..780138d6c6bcd 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -223,12 +223,12 @@ function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, >k2 : keyof T & keyof U x[k3]; // Error ->x[k3] : (T | U)[keyof T | keyof U] +>x[k3] : any >x : T | U >k3 : keyof T | keyof U x[k4]; // Error ->x[k4] : (T | U)[keyof T | keyof U] +>x[k4] : any >x : T | U >k4 : keyof T | keyof U diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 60a06e000c255..d66312c0f178e 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -3,12 +3,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(11,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(16,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(20,5): error TS2536: Type 'keyof U' cannot be used to index type 'T'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,5): error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. - Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,12): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(25,5): error TS2536: Type 'K' cannot be used to index type 'T'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,12): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. @@ -17,13 +13,24 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T' is not assignable to type 'U'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[keyof T] | undefined'. + Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. + Type 'T[string]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. + Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T' is not assignable to type 'U'. + Type 'T[keyof T]' is not assignable to type 'U[K] | undefined'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[K] | undefined'. + Type 'T[string]' is not assignable to type 'U[K] | undefined'. + Type 'T[string]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. + Type 'T[keyof T]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. + Type 'T[K]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. @@ -60,7 +67,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (30 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (28 errors) ==== function f1(x: T, k: keyof T) { return x[k]; } @@ -90,9 +97,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~~~~ !!! error TS2536: Type 'keyof U' cannot be used to index type 'T'. y[k] = x[k]; // Error - ~~~~ -!!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'keyof U' cannot be used to index type 'T'. } @@ -102,9 +106,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~~~~ !!! error TS2536: Type 'K' cannot be used to index type 'T'. y[k] = x[k]; // Error - ~~~~ -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'K' cannot be used to index type 'T'. } @@ -133,8 +134,12 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[keyof T] | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f13(x: T, y: Partial, k: K) { @@ -145,8 +150,15 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[K] | undefined'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[K] | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f20(x: T, y: Readonly, k: keyof T) { diff --git a/tests/baselines/reference/mappedTypeRelationships.types b/tests/baselines/reference/mappedTypeRelationships.types index 582d777149c56..0922ee18340bc 100644 --- a/tests/baselines/reference/mappedTypeRelationships.types +++ b/tests/baselines/reference/mappedTypeRelationships.types @@ -79,7 +79,7 @@ function f5(x: T, y: U, k: keyof U) { x[k] = y[k]; // Error >x[k] = y[k] : U[keyof U] ->x[k] : T[keyof U] +>x[k] : any >x : T >k : keyof U >y[k] : U[keyof U] @@ -87,11 +87,11 @@ function f5(x: T, y: U, k: keyof U) { >k : keyof U y[k] = x[k]; // Error ->y[k] = x[k] : T[keyof U] +>y[k] = x[k] : any >y[k] : U[keyof U] >y : U >k : keyof U ->x[k] : T[keyof U] +>x[k] : any >x : T >k : keyof U } @@ -104,7 +104,7 @@ function f6(x: T, y: U, k: K) { x[k] = y[k]; // Error >x[k] = y[k] : U[K] ->x[k] : T[K] +>x[k] : any >x : T >k : K >y[k] : U[K] @@ -112,11 +112,11 @@ function f6(x: T, y: U, k: K) { >k : K y[k] = x[k]; // Error ->y[k] = x[k] : T[K] +>y[k] = x[k] : any >y[k] : U[K] >y : U >k : K ->x[k] : T[K] +>x[k] : any >x : T >k : K } diff --git a/tests/baselines/reference/mappedTypes6.errors.txt b/tests/baselines/reference/mappedTypes6.errors.txt index cbe4c58d27e3c..3c5c8eac2ed4e 100644 --- a/tests/baselines/reference/mappedTypes6.errors.txt +++ b/tests/baselines/reference/mappedTypes6.errors.txt @@ -3,6 +3,9 @@ tests/cases/conformance/types/mapped/mappedTypes6.ts(24,5): error TS2322: Type ' tests/cases/conformance/types/mapped/mappedTypes6.ts(27,5): error TS2322: Type 'Partial' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypes6.ts(37,5): error TS2322: Type 'Required' is not assignable to type 'Denullified'. Type 'T[P]' is not assignable to type 'NonNullable'. + Type 'T[keyof T]' is not assignable to type 'NonNullable'. + Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'NonNullable'. + Type 'T[string]' is not assignable to type 'NonNullable'. tests/cases/conformance/types/mapped/mappedTypes6.ts(38,5): error TS2322: Type 'T' is not assignable to type 'Denullified'. tests/cases/conformance/types/mapped/mappedTypes6.ts(39,5): error TS2322: Type 'Partial' is not assignable to type 'Denullified'. tests/cases/conformance/types/mapped/mappedTypes6.ts(42,5): error TS2322: Type 'T' is not assignable to type 'Required'. @@ -67,6 +70,9 @@ tests/cases/conformance/types/mapped/mappedTypes6.ts(120,4): error TS2540: Canno ~ !!! error TS2322: Type 'Required' is not assignable to type 'Denullified'. !!! error TS2322: Type 'T[P]' is not assignable to type 'NonNullable'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'NonNullable'. +!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'NonNullable'. +!!! error TS2322: Type 'T[string]' is not assignable to type 'NonNullable'. w = y; // Error ~ !!! error TS2322: Type 'T' is not assignable to type 'Denullified'. diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt index e63f360e24197..14c97cb148c1a 100644 --- a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt @@ -3,6 +3,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessTy tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(9,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(12,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(15,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(18,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(21,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(24,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. @@ -36,6 +37,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessTy tp = s; ~~ !!! error TS2322: Type 'string' is not assignable to type 'T[P]'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. } function k(s: string, tp: T[P]): void { tp = s; diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt index 9fda31a7cbcf1..a480d4f3e4e50 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -11,31 +11,22 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] | GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] | GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type '(TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]) | GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string] | GetProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. - Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'GetProps[Extract>] | (TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. + Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. + Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. ==== tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== @@ -129,31 +120,22 @@ tests/cases/compiler/reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): !!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. !!! error TS2344: Type '(Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]) | (Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. !!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]) | GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] | GetProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]) | GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] | GetProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type '(TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]) | GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string] | GetProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. -!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string] | (TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string] | (TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. +!!! error TS2344: Type 'GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & string] extends GetProps[keyof TInjectedProps & string] ? GetProps[keyof TInjectedProps & string] : TInjectedProps[keyof TInjectedProps & string] : GetProps[string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'keyof GetProps & string extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & keyof GetProps & string] extends GetProps[keyof TInjectedProps & keyof GetProps & string] ? GetProps[keyof TInjectedProps & keyof GetProps & string] : TInjectedProps[keyof TInjectedProps & keyof GetProps & string] : GetProps[keyof GetProps & string]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[keyof TInjectedProps & Extract>] extends GetProps[keyof TInjectedProps & Extract>] ? GetProps[keyof TInjectedProps & Extract>] : TInjectedProps[keyof TInjectedProps & Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'Extract> extends keyof TInjectedProps ? TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : TInjectedProps[Extract>] : GetProps[Extract>]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. +!!! error TS2344: Type 'P extends keyof TInjectedProps ? TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P] : GetProps[P]' is not assignable to type 'TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never'. >; declare const connect: { diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts new file mode 100644 index 0000000000000..2d96e20f12a9d --- /dev/null +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts @@ -0,0 +1,112 @@ +// @strict: true +// @target: esnext + +function f1(obj: { a: number, b: 0 | 1, c: string }, k0: 'a', k1: 'a' | 'b', k2: 'a' | 'b' | 'c') { + obj[k0] = 1; + obj[k0] = 2; + obj[k0] = 'x'; // Error + obj[k1] = 1; + obj[k1] = 2; // Error + obj[k1] = 'x'; // Error + obj[k2] = 1; // Error + obj[k2] = 2; // Error + obj[k2] = 'x'; // Error +} + +function f2(a: { x: number, y: number }, b: { [key: string]: number }, c: T, k: keyof T) { + a = b; // Error, index signature in source doesn't imply properties are present + a = c; // Error, index signature in source doesn't imply properties are present + b = a; + b = c; + c = a; // Error, constraint on target doesn't imply any properties or signatures + c = b; // Error, constraint on target doesn't imply any properties or signatures + a.x; + b.x; + c.x; + c[k]; + a.x = 1; + b.x = 1; + c.x = 1; // Error, cannot write to index signature through constraint + c[k] = 1; // Error, cannot write to index signature through constraint +} + +function f3(a: { [P in K]: number }, b: { [key: string]: number }, k: K) { + a = b; // Error, index signature doesn't imply properties are present + b = a; + a[k]; + a[k] = 1; +} + +function f3b(a: { [P in K]: number }, b: { [P in string]: number }, k: K) { + a = b; // Error, index signature doesn't imply properties are present + b = a; +} + +function f4(a: { [key: string]: number }[K], b: number) { + a = b; + b = a; +} + +type Item = { a: string, b: number }; + +function f10(obj: T, k1: string, k2: keyof Item, k3: keyof T, k4: K) { + obj[k1] = 123; // Error + obj[k2] = 123; // Error + obj[k3] = 123; // Error + obj[k4] = 123; // Error +} + +type Dict = Record; + +function f11(obj: Dict, k1: keyof Dict, k2: K) { + obj.foo = 123; + obj[k1] = 123; + obj[k2] = 123; +} + +function f12, K extends keyof T>(obj: T, k1: keyof Dict, k2: keyof T, k3: K) { + obj.foo = 123; // Error + obj[k1] = 123; // Error + obj[k2] = 123; // Error + obj[k3] = 123; // Error +} + +// Repro from #27895 + +export interface Entity { + id: number | string; +} + +export type IdOf = E['id']; + +export interface EntityState { + ids: IdOf[]; + entities: { [key: string]: E, [key: number]: E }; +} + + +export function getAllEntities(state: EntityState): E[] { + const { ids, entities } = state; + return ids.map(id => entities[id]); +} + +export function getEntity(id: IdOf, state: EntityState): E | undefined { + const { ids, entities } = state; + + if (!ids.includes(id)) { + return undefined; + } + + return entities[id]; +} + +// Repro from #30603 + +interface Type { + a: 123; + b: "some string"; +} + +function get123(): Type[K] { + return 123; // Error +}