From c0ae93f3570b2886154720ae40b2983aabf7d763 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Oct 2023 11:24:33 -0700 Subject: [PATCH 1/9] Fix constraint of conditional type applied to constrained type variable --- src/compiler/checker.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58d6a8b867e20..5d0d59523b9d8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13571,7 +13571,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const checkType = (type as ConditionalType).checkType; const constraint = getLowerBoundOfKeyType(checkType); if (constraint !== checkType) { - return getConditionalTypeInstantiation(type as ConditionalType, prependTypeMapping((type as ConditionalType).root.checkType, constraint, (type as ConditionalType).mapper)); + return getConditionalTypeInstantiation(type as ConditionalType, prependTypeMapping((type as ConditionalType).root.checkType, constraint, (type as ConditionalType).mapper), /*forConstraint*/ false); } } return type; @@ -14020,7 +14020,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const simplified = getSimplifiedType(type.checkType, /*writing*/ false); const constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified; if (constraint && constraint !== type.checkType) { - const instantiated = getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper)); + const instantiated = getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper), /*forConstraint*/ true); if (!(instantiated.flags & TypeFlags.Never)) { type.resolvedConstraintOfDistributive = instantiated; return instantiated; @@ -18243,7 +18243,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isGenericType(type) || checkTuples && isTupleType(type) && some(getElementTypes(type), isGenericType); } - function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function getConditionalType(root: ConditionalRoot, mapper: TypeMapper | undefined, forConstraint: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { let result; let extraTypes: Type[] | undefined; let tailCount = 0; @@ -18323,7 +18323,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // then no instantiations will be and we can just return the false branch type. if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (checkType.flags & TypeFlags.Any || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) { // Return union of trueType and falseType for 'any' since it matches anything - if (checkType.flags & TypeFlags.Any) { + if (checkType.flags & TypeFlags.Any || forConstraint && areTypesComparable(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) { (extraTypes || (extraTypes = [])).push(instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper)); } // If falseType is an immediately nested conditional type that isn't distributive or has an @@ -18447,7 +18447,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { aliasSymbol, aliasTypeArguments, }; - links.resolvedType = getConditionalType(root, /*mapper*/ undefined); + links.resolvedType = getConditionalType(root, /*mapper*/ undefined, /*forConstraint*/ false); if (outerTypeParameters) { root.instantiations = new Map(); root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType); @@ -19454,14 +19454,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result; } - function getConditionalTypeInstantiation(type: ConditionalType, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { + function getConditionalTypeInstantiation(type: ConditionalType, mapper: TypeMapper, forConstraint: boolean, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { const root = type.root; if (root.outerTypeParameters) { // We are instantiating a conditional type that has one or more type parameters in scope. Apply the // mapper to the type parameters to produce the effective list of type arguments, and compute the // instantiation cache key from the type IDs of the type arguments. const typeArguments = map(root.outerTypeParameters, t => getMappedType(t, mapper)); - const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); + const id = (forConstraint ? "C" : "") + getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); let result = root.instantiations!.get(id); if (!result) { const newMapper = createTypeMapper(root.outerTypeParameters, typeArguments); @@ -19471,8 +19471,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the // result is (A extends U ? X : Y) | (B extends U ? X : Y). result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ? - mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments) : - getConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments); + mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper), forConstraint), aliasSymbol, aliasTypeArguments) : + getConditionalType(root, newMapper, forConstraint, aliasSymbol, aliasTypeArguments); root.instantiations!.set(id, result); } return result; @@ -19554,7 +19554,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getIndexedAccessType(instantiateType((type as IndexedAccessType).objectType, mapper), instantiateType((type as IndexedAccessType).indexType, mapper), (type as IndexedAccessType).accessFlags, /*accessNode*/ undefined, newAliasSymbol, newAliasTypeArguments); } if (flags & TypeFlags.Conditional) { - return getConditionalTypeInstantiation(type as ConditionalType, combineTypeMappers((type as ConditionalType).mapper, mapper), aliasSymbol, aliasTypeArguments); + return getConditionalTypeInstantiation(type as ConditionalType, combineTypeMappers((type as ConditionalType).mapper, mapper), /*forConstraint*/ false, aliasSymbol, aliasTypeArguments); } if (flags & TypeFlags.Substitution) { const newBaseType = instantiateType((type as SubstitutionType).baseType, mapper); From 03a45f456d10641e3cc6d91d1b94dc4757aed6b2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Oct 2023 17:27:26 -0700 Subject: [PATCH 2/9] Accept new baselines --- ...nalNoInfiniteInstantiationDepth.errors.txt | 2 ++ .../flatArrayNoExcessiveStackDepth.errors.txt | 26 ++++++------------- .../flatArrayNoExcessiveStackDepth.types | 4 +-- ...ferredInferenceAllowsAssignment.errors.txt | 2 ++ 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt index 4078a255dfcb4..73089354dc7f0 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -26,6 +26,7 @@ circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth Type 'GetProps[keyof TInjectedProps & keyof 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) | undefined'. 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'. ==== circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== @@ -121,4 +122,5 @@ circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth !!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof 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) | undefined'. !!! 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'. \ No newline at end of file diff --git a/tests/baselines/reference/flatArrayNoExcessiveStackDepth.errors.txt b/tests/baselines/reference/flatArrayNoExcessiveStackDepth.errors.txt index 83a977588577f..fee12ed489776 100644 --- a/tests/baselines/reference/flatArrayNoExcessiveStackDepth.errors.txt +++ b/tests/baselines/reference/flatArrayNoExcessiveStackDepth.errors.txt @@ -1,12 +1,7 @@ -flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr' is not assignable to type 'FlatArray'. - Type 'unknown' is not assignable to type 'FlatArray'. - Type 'unknown' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. - Type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. - Type 'unknown' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. - Type 'FlatArray' is not assignable to type 'FlatArray'. - Type 'InnerArr' is not assignable to type 'FlatArray'. - Type 'InnerArr' is not assignable to type '(InnerArr extends readonly (infer InnerArr)[] ? FlatArray : InnerArr) & InnerArr'. - Type 'InnerArr' is not assignable to type 'InnerArr extends readonly (infer InnerArr)[] ? FlatArray : InnerArr'. +flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'FlatArray' is not assignable to type 'FlatArray'. + Type 'Arr' is not assignable to type 'FlatArray'. + Type 'Arr' is not assignable to type '(Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr) & Arr'. + Type 'Arr' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. ==== flatArrayNoExcessiveStackDepth.ts (1 errors) ==== @@ -31,14 +26,9 @@ flatArrayNoExcessiveStackDepth.ts(20,5): error TS2322: Type 'Arr extends readonl x = y; y = x; // Error ~ -!!! error TS2322: Type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr' is not assignable to type 'FlatArray'. -!!! error TS2322: Type 'unknown' is not assignable to type 'FlatArray'. -!!! error TS2322: Type 'unknown' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. -!!! error TS2322: Type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. -!!! error TS2322: Type 'unknown' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. -!!! error TS2322: Type 'FlatArray' is not assignable to type 'FlatArray'. -!!! error TS2322: Type 'InnerArr' is not assignable to type 'FlatArray'. -!!! error TS2322: Type 'InnerArr' is not assignable to type '(InnerArr extends readonly (infer InnerArr)[] ? FlatArray : InnerArr) & InnerArr'. -!!! error TS2322: Type 'InnerArr' is not assignable to type 'InnerArr extends readonly (infer InnerArr)[] ? FlatArray : InnerArr'. +!!! error TS2322: Type 'FlatArray' is not assignable to type 'FlatArray'. +!!! error TS2322: Type 'Arr' is not assignable to type 'FlatArray'. +!!! error TS2322: Type 'Arr' is not assignable to type '(Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr) & Arr'. +!!! error TS2322: Type 'Arr' is not assignable to type 'Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr'. } \ No newline at end of file diff --git a/tests/baselines/reference/flatArrayNoExcessiveStackDepth.types b/tests/baselines/reference/flatArrayNoExcessiveStackDepth.types index eef8873f0f8a4..118c4c736d5e1 100644 --- a/tests/baselines/reference/flatArrayNoExcessiveStackDepth.types +++ b/tests/baselines/reference/flatArrayNoExcessiveStackDepth.types @@ -65,8 +65,8 @@ function f(x: FlatArray, y: FlatArray) >y : FlatArray y = x; // Error ->y = x : Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr +>y = x : FlatArray >y : FlatArray ->x : Arr extends readonly (infer InnerArr)[] ? FlatArray : Arr +>x : FlatArray } diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt index 1da209dad928e..585ecdeffe438 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -26,6 +26,7 @@ reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): error TS2344: Type 'G Type 'GetProps[keyof TInjectedProps & keyof 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) | undefined'. 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'. ==== reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== @@ -134,6 +135,7 @@ reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): error TS2344: Type 'G !!! error TS2344: Type 'GetProps[keyof TInjectedProps & keyof 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) | undefined'. !!! 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'. >; declare const connect: { From 388daf5bb4e92df7ba4683d3483b89fefd5896af Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Oct 2023 17:33:41 -0700 Subject: [PATCH 3/9] Shrink some error pyramids --- src/compiler/checker.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5d0d59523b9d8..0da5650397157 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22303,18 +22303,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } - else { - // conditionals aren't related to one another via distributive constraint as it is much too inaccurate and allows way - // more assignments than are desirable (since it maps the source check type to its constraint, it loses information) - const distributiveConstraint = hasNonCircularBaseConstraint(source) ? getConstraintOfDistributiveConditionalType(source as ConditionalType) : undefined; - if (distributiveConstraint) { - if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) { - return result; - } - } - } - - // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` + // conditionals can be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O` // when `O` is a conditional (`never` is trivially assignable to `O`, as is `O`!). const defaultConstraint = getDefaultConstraintOfConditionalType(source as ConditionalType); if (defaultConstraint) { @@ -22322,6 +22311,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result; } } + // conditionals aren't related to one another via distributive constraint as it is much too inaccurate and allows way + // more assignments than are desirable (since it maps the source check type to its constraint, it loses information). + const distributiveConstraint = !(targetFlags & TypeFlags.Conditional) && hasNonCircularBaseConstraint(source) ? getConstraintOfDistributiveConditionalType(source as ConditionalType) : undefined; + if (distributiveConstraint) { + resetErrorInfo(saveErrorInfo); + if (result = isRelatedTo(distributiveConstraint, target, RecursionFlags.Source, reportErrors)) { + return result; + } + } } else { // An empty object type is related to any mapped type that includes a '?' modifier. From 5082d173b49a38c6a6ee1c89764e517be6a2080a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Oct 2023 17:34:16 -0700 Subject: [PATCH 4/9] Accept new baselines --- ...nalNoInfiniteInstantiationDepth.errors.txt | 72 +++++-------------- .../reference/conditionalTypes1.errors.txt | 12 ++-- .../reference/conditionalTypes2.errors.txt | 11 ++- ...wnNotAssignableToConcreteObject.errors.txt | 35 ++++----- .../keyofAndIndexedAccessErrors.errors.txt | 12 ++-- ...ferredInferenceAllowsAssignment.errors.txt | 72 +++++-------------- 6 files changed, 60 insertions(+), 154 deletions(-) diff --git a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt index 73089354dc7f0..8a32b0c580737 100644 --- a/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt +++ b/tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt @@ -1,32 +1,12 @@ circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts(63,84): error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. - Type 'unknown' is not assignable to type 'Shared>'. - Type 'Matching>' is not assignable to type 'Shared>'. - 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) | undefined'. - Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[P]' 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 '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) | undefined'. - Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : 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>] | GetProps[Extract>] | 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) | undefined'. - Type 'GetProps[keyof 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) | 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>]) | (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 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & Extract>]' 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 '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 '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 TInjectedProps & keyof 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) | undefined'. - 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 'Matching>' is not assignable to type 'Shared>'. + 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) | undefined'. + 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) | 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>]) | (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 '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 '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'. ==== circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.ts (1 errors) ==== @@ -95,32 +75,12 @@ circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth ) => ConnectedComponentClass, keyof Shared>> & TNeedsProps>; ~~~~~~~~~~~ !!! error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. -!!! error TS2344: Type 'unknown' is not assignable to type 'Shared>'. -!!! error TS2344: Type 'Matching>' is not assignable to type 'Shared>'. -!!! 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) | undefined'. -!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[P]' 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 '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) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : 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>] | GetProps[Extract>] | 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) | 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[string]' 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>]) | (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 '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[keyof TInjectedProps & Extract>]' 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 '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 '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 TInjectedProps & keyof 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) | undefined'. -!!! 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 'Matching>' is not assignable to type 'Shared>'. +!!! 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) | undefined'. +!!! 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) | 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>]) | (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 '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 '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'. \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 6c6443b045c59..c3b5f377180ff 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -57,8 +57,10 @@ conditionalTypes1.ts(136,22): error TS2540: Cannot assign to 'id' because it is conditionalTypes1.ts(137,10): error TS2339: Property 'updatePart' does not exist on type 'DeepReadonlyObject'. conditionalTypes1.ts(159,5): error TS2322: Type 'ZeroOf' is not assignable to type 'T'. 'ZeroOf' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. - Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'. - 'T' could be instantiated with an arbitrary type which could be unrelated to '0 | (T extends string ? "" : false)'. + Type 'string | number' is not assignable to type 'T'. + 'string | number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. + Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf'. Type 'string | number' is not assignable to type 'ZeroOf'. Type 'string' is not assignable to type 'ZeroOf'. @@ -306,8 +308,10 @@ conditionalTypes1.ts(288,43): error TS2322: Type 'T95' is not assignable to t ~ !!! error TS2322: Type 'ZeroOf' is not assignable to type 'T'. !!! error TS2322: 'ZeroOf' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. -!!! error TS2322: Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'. -!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to '0 | (T extends string ? "" : false)'. +!!! error TS2322: Type 'string | number' is not assignable to type 'T'. +!!! error TS2322: 'string | number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. +!!! error TS2322: Type 'string' is not assignable to type 'T'. +!!! error TS2322: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'. y = x; // Error ~ !!! error TS2322: Type 'T' is not assignable to type 'ZeroOf'. diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index ef0eab5c43e39..de78fe2d373c3 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -25,9 +25,8 @@ conditionalTypes2.ts(25,5): error TS2322: Type 'Invariant' is not assignable Type 'A' is not assignable to type 'B'. 'B' could be instantiated with an arbitrary type which could be unrelated to 'A'. conditionalTypes2.ts(73,12): error TS2345: Argument of type 'Extract, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'. - Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. - Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. - Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. + Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. + Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. conditionalTypes2.ts(74,12): error TS2345: Argument of type 'Extract' is not assignable to parameter of type '{ foo: string; bat: string; }'. Property 'bat' is missing in type 'Foo & Bar' but required in type '{ foo: string; bat: string; }'. conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2' is not assignable to parameter of type '{ foo: string; bat: string; }'. @@ -145,10 +144,8 @@ conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'. -!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. -!!! error TS2345: Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. -!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. -!!! related TS2728 conditionalTypes2.ts:62:43: 'bat' is declared here. +!!! error TS2345: Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. +!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'. !!! related TS2728 conditionalTypes2.ts:62:43: 'bat' is declared here. fooBat(y); // Error ~ diff --git a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt index 5fd7c1452695b..ad660643bd706 100644 --- a/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt +++ b/tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt @@ -1,15 +1,10 @@ genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts(13,5): error TS2322: Type 'ReturnType' is not assignable to type 'A'. - Type 'unknown' is not assignable to type 'A'. - Type 'ReturnType' is not assignable to type 'A'. - Type 'unknown' is not assignable to type 'A'. - Type 'ReturnType' is not assignable to type 'A'. - Type 'unknown' is not assignable to type 'A'. - Type 'ReturnType | ReturnType | ReturnType' is not assignable to type 'A'. - Type 'ReturnType' is not assignable to type 'A'. - Type 'unknown' is not assignable to type 'A'. - Type 'ReturnType[string]>' is not assignable to type 'A'. - Type 'unknown' is not assignable to type 'A'. - Property 'x' is missing in type '{}' but required in type 'A'. + Type 'ReturnType' is not assignable to type 'A'. + Type 'ReturnType' is not assignable to type 'A'. + Type 'ReturnType | ReturnType | ReturnType' is not assignable to type 'A'. + Type 'ReturnType' is not assignable to type 'A'. + Type 'ReturnType[string]>' is not assignable to type 'A'. + Type 'unknown' is not assignable to type 'A'. ==== genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ==== @@ -28,18 +23,12 @@ genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts(13,5): er x = a2; ~ !!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. -!!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. -!!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. -!!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Type 'ReturnType | ReturnType | ReturnType' is not assignable to type 'A'. -!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. -!!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Type 'ReturnType[string]>' is not assignable to type 'A'. -!!! error TS2322: Type 'unknown' is not assignable to type 'A'. -!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'. -!!! related TS2728 genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here. +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType | ReturnType | ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType' is not assignable to type 'A'. +!!! error TS2322: Type 'ReturnType[string]>' is not assignable to type 'A'. +!!! error TS2322: Type 'unknown' is not assignable to type 'A'. } // Original CFA report of the above issue diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 803940642b128..e19b848ab74b1 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -40,10 +40,8 @@ keyofAndIndexedAccessErrors.ts(87,5): error TS2322: Type 'keyof T | keyof U' is Type 'keyof T' is not assignable to type 'keyof T & keyof U'. keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract' is not assignable to type 'K'. 'Extract' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. - Type 'string & keyof T' is not assignable to type 'K'. - 'string & keyof T' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. - Type 'string' is not assignable to type 'K'. - 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. + Type 'string' is not assignable to type 'K'. + 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. Type 'Extract' is not assignable to type 'K'. 'Extract' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. @@ -247,10 +245,8 @@ keyofAndIndexedAccessErrors.ts(165,5): error TS2322: Type 'number' is not assign ~ !!! error TS2322: Type 'Extract' is not assignable to type 'K'. !!! error TS2322: 'Extract' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. -!!! error TS2322: Type 'string & keyof T' is not assignable to type 'K'. -!!! error TS2322: 'string & keyof T' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. -!!! error TS2322: Type 'string' is not assignable to type 'K'. -!!! error TS2322: 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. +!!! error TS2322: 'string' is assignable to the constraint of type 'K', but 'K' could be instantiated with a different subtype of constraint 'string'. t[key] = tk; // ok, T[K] ==> T[keyof T] tk = t[key]; // error, T[keyof T] =/=> T[K] ~~ diff --git a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt index 585ecdeffe438..73e20f3dce297 100644 --- a/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt +++ b/tests/baselines/reference/reactReduxLikeDeferredInferenceAllowsAssignment.errors.txt @@ -1,32 +1,12 @@ reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. - Type 'unknown' is not assignable to type 'Shared>'. - Type 'Matching>' is not assignable to type 'Shared>'. - 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) | undefined'. - Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[P]' 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 '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) | undefined'. - Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : 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>] | GetProps[Extract>] | 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) | undefined'. - Type 'GetProps[keyof 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) | 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>]) | (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 'GetProps[keyof TInjectedProps & Extract>] | TInjectedProps[keyof TInjectedProps & Extract>]' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. - Type 'GetProps[keyof TInjectedProps & Extract>]' 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 '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 '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 TInjectedProps & keyof 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) | undefined'. - 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 'Matching>' is not assignable to type 'Shared>'. + 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) | undefined'. + 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) | 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>]) | (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 '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 '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'. ==== reactReduxLikeDeferredInferenceAllowsAssignment.ts (1 errors) ==== @@ -108,34 +88,14 @@ reactReduxLikeDeferredInferenceAllowsAssignment.ts(76,50): error TS2344: Type 'G Omit, keyof Shared>> & TNeedsProps ~~~~~~~~~~~ !!! error TS2344: Type 'GetProps' does not satisfy the constraint 'Shared>'. -!!! error TS2344: Type 'unknown' is not assignable to type 'Shared>'. -!!! error TS2344: Type 'Matching>' is not assignable to type 'Shared>'. -!!! 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) | undefined'. -!!! error TS2344: Type 'GetProps[P] | (TInjectedProps[P] extends GetProps[P] ? GetProps[P] : TInjectedProps[P])' is not assignable to type '(TInjectedProps[P] extends GetProps[P] ? GetProps[P] : never) | undefined'. -!!! error TS2344: Type 'GetProps[P]' 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 '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) | undefined'. -!!! error TS2344: Type 'GetProps[Extract>] | (TInjectedProps[Extract>] extends GetProps[Extract>] ? GetProps[Extract>] : 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>] | GetProps[Extract>] | 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) | 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[string]' 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>]) | (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 '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[keyof TInjectedProps & Extract>]' 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 '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 '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 TInjectedProps & keyof 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) | undefined'. -!!! 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 'Matching>' is not assignable to type 'Shared>'. +!!! 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) | undefined'. +!!! 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) | 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>]) | (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 '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 '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'. >; declare const connect: { From 2f5d9e9a6fa227b9da47acdecb1a80bfb3551818 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Oct 2023 17:39:44 -0700 Subject: [PATCH 5/9] Add tests --- ...utiveConditionalTypeConstraints.errors.txt | 108 +++++++++ ...ributiveConditionalTypeConstraints.symbols | 225 ++++++++++++++++++ ...stributiveConditionalTypeConstraints.types | 202 ++++++++++++++++ .../distributiveConditionalTypeConstraints.ts | 86 +++++++ 4 files changed, 621 insertions(+) create mode 100644 tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt create mode 100644 tests/baselines/reference/distributiveConditionalTypeConstraints.symbols create mode 100644 tests/baselines/reference/distributiveConditionalTypeConstraints.types create mode 100644 tests/cases/compiler/distributiveConditionalTypeConstraints.ts diff --git a/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt b/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt new file mode 100644 index 0000000000000..2b455f4e2eebd --- /dev/null +++ b/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt @@ -0,0 +1,108 @@ +distributiveConditionalTypeConstraints.ts(4,9): error TS2322: Type 'boolean' is not assignable to type 'true'. +distributiveConditionalTypeConstraints.ts(5,9): error TS2322: Type 'boolean' is not assignable to type 'false'. +distributiveConditionalTypeConstraints.ts(10,9): error TS2322: Type 'IsArray' is not assignable to type 'false'. + Type 'true' is not assignable to type 'false'. +distributiveConditionalTypeConstraints.ts(15,9): error TS2322: Type 'IsArray' is not assignable to type 'false'. + Type 'true' is not assignable to type 'false'. +distributiveConditionalTypeConstraints.ts(19,9): error TS2322: Type 'IsArray' is not assignable to type 'true'. + Type 'false' is not assignable to type 'true'. + + +==== distributiveConditionalTypeConstraints.ts (5 errors) ==== + type IsArray = T extends unknown[] ? true : false; + + function f1(x: IsArray) { + let t: true = x; // Error + ~ +!!! error TS2322: Type 'boolean' is not assignable to type 'true'. + let f: false = x; // Error + ~ +!!! error TS2322: Type 'boolean' is not assignable to type 'false'. + } + + function f2(x: IsArray) { + let t: true = x; + let f: false = x; // Error + ~ +!!! error TS2322: Type 'IsArray' is not assignable to type 'false'. +!!! error TS2322: Type 'true' is not assignable to type 'false'. + } + + function f3(x: IsArray) { + let t: true = x; + let f: false = x; // Error + ~ +!!! error TS2322: Type 'IsArray' is not assignable to type 'false'. +!!! error TS2322: Type 'true' is not assignable to type 'false'. + } + + function f4(x: IsArray) { + let t: true = x; // Error + ~ +!!! error TS2322: Type 'IsArray' is not assignable to type 'true'. +!!! error TS2322: Type 'false' is not assignable to type 'true'. + let f: false = x; + } + + type ZeroOf = + T extends null ? null : + T extends undefined ? undefined : + T extends string ? "" : + T extends number ? 0 : + T extends boolean ? false : + never; + + function f10(x: ZeroOf) { + let t: "" | 0 | false = x; + } + + // Modified repro from #30152 + + interface A { foo(): void; } + interface B { bar(): void; } + interface C { foo(): void, bar(): void } + + function test1(y: T extends B ? number : string) { + if (typeof y == 'string') { + y; // T extends B ? number : string + } + else { + y; // never + } + const newY: string | number = y; + newY; // string + } + + function test2(y: T extends B ? string : number) { + if (typeof y == 'string') { + y; // never + } + else { + y; // T extends B ? string : number + } + const newY: string | number = y; + newY; // number + } + + function test3(y: T extends C ? number : string) { + if (typeof y == 'string') { + y; // (T extends C ? number : string) & string + } + else { + y; // T extends C ? number : string + } + const newY: string | number = y; + newY; // string | number + } + + function test4(y: T extends C ? string : number) { + if (typeof y == 'string') { + y; // (T extends C ? string : number) & string + } + else { + y; // T extends C ? string : number + } + const newY: string | number = y; + newY; // string | number + } + \ No newline at end of file diff --git a/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols b/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols new file mode 100644 index 0000000000000..762237abde362 --- /dev/null +++ b/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols @@ -0,0 +1,225 @@ +//// [tests/cases/compiler/distributiveConditionalTypeConstraints.ts] //// + +=== distributiveConditionalTypeConstraints.ts === +type IsArray = T extends unknown[] ? true : false; +>IsArray : Symbol(IsArray, Decl(distributiveConditionalTypeConstraints.ts, 0, 0)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 0, 13)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 0, 13)) + +function f1(x: IsArray) { +>f1 : Symbol(f1, Decl(distributiveConditionalTypeConstraints.ts, 0, 53)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 2, 12)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 2, 30)) +>IsArray : Symbol(IsArray, Decl(distributiveConditionalTypeConstraints.ts, 0, 0)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 2, 12)) + + let t: true = x; // Error +>t : Symbol(t, Decl(distributiveConditionalTypeConstraints.ts, 3, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 2, 30)) + + let f: false = x; // Error +>f : Symbol(f, Decl(distributiveConditionalTypeConstraints.ts, 4, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 2, 30)) +} + +function f2(x: IsArray) { +>f2 : Symbol(f2, Decl(distributiveConditionalTypeConstraints.ts, 5, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 7, 12)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 7, 33)) +>IsArray : Symbol(IsArray, Decl(distributiveConditionalTypeConstraints.ts, 0, 0)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 7, 12)) + + let t: true = x; +>t : Symbol(t, Decl(distributiveConditionalTypeConstraints.ts, 8, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 7, 33)) + + let f: false = x; // Error +>f : Symbol(f, Decl(distributiveConditionalTypeConstraints.ts, 9, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 7, 33)) +} + +function f3(x: IsArray) { +>f3 : Symbol(f3, Decl(distributiveConditionalTypeConstraints.ts, 10, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 12, 12)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 12, 32)) +>IsArray : Symbol(IsArray, Decl(distributiveConditionalTypeConstraints.ts, 0, 0)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 12, 12)) + + let t: true = x; +>t : Symbol(t, Decl(distributiveConditionalTypeConstraints.ts, 13, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 12, 32)) + + let f: false = x; // Error +>f : Symbol(f, Decl(distributiveConditionalTypeConstraints.ts, 14, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 12, 32)) +} + +function f4(x: IsArray) { +>f4 : Symbol(f4, Decl(distributiveConditionalTypeConstraints.ts, 15, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 17, 12)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 17, 32)) +>IsArray : Symbol(IsArray, Decl(distributiveConditionalTypeConstraints.ts, 0, 0)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 17, 12)) + + let t: true = x; // Error +>t : Symbol(t, Decl(distributiveConditionalTypeConstraints.ts, 18, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 17, 32)) + + let f: false = x; +>f : Symbol(f, Decl(distributiveConditionalTypeConstraints.ts, 19, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 17, 32)) +} + +type ZeroOf = +>ZeroOf : Symbol(ZeroOf, Decl(distributiveConditionalTypeConstraints.ts, 20, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 22, 12)) + + T extends null ? null : +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 22, 12)) + + T extends undefined ? undefined : +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 22, 12)) + + T extends string ? "" : +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 22, 12)) + + T extends number ? 0 : +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 22, 12)) + + T extends boolean ? false : +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 22, 12)) + + never; + +function f10(x: ZeroOf) { +>f10 : Symbol(f10, Decl(distributiveConditionalTypeConstraints.ts, 28, 10)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 30, 13)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 30, 27)) +>ZeroOf : Symbol(ZeroOf, Decl(distributiveConditionalTypeConstraints.ts, 20, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 30, 13)) + + let t: "" | 0 | false = x; +>t : Symbol(t, Decl(distributiveConditionalTypeConstraints.ts, 31, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 30, 27)) +} + +// Modified repro from #30152 + +interface A { foo(): void; } +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>foo : Symbol(A.foo, Decl(distributiveConditionalTypeConstraints.ts, 36, 13)) + +interface B { bar(): void; } +>B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 36, 28)) +>bar : Symbol(B.bar, Decl(distributiveConditionalTypeConstraints.ts, 37, 13)) + +interface C { foo(): void, bar(): void } +>C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 37, 28)) +>foo : Symbol(C.foo, Decl(distributiveConditionalTypeConstraints.ts, 38, 13)) +>bar : Symbol(C.bar, Decl(distributiveConditionalTypeConstraints.ts, 38, 26)) + +function test1(y: T extends B ? number : string) { +>test1 : Symbol(test1, Decl(distributiveConditionalTypeConstraints.ts, 38, 40)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 40, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 40, 15)) +>B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 36, 28)) + + if (typeof y == 'string') { +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) + + y; // T extends B ? number : string +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) + } + else { + y; // never +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) + } + const newY: string | number = y; +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 47, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) + + newY; // string +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 47, 9)) +} + +function test2(y: T extends B ? string : number) { +>test2 : Symbol(test2, Decl(distributiveConditionalTypeConstraints.ts, 49, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 51, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 51, 15)) +>B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 36, 28)) + + if (typeof y == 'string') { +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) + + y; // never +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) + } + else { + y; // T extends B ? string : number +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) + } + const newY: string | number = y; +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 58, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) + + newY; // number +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 58, 9)) +} + +function test3(y: T extends C ? number : string) { +>test3 : Symbol(test3, Decl(distributiveConditionalTypeConstraints.ts, 60, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 62, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 62, 15)) +>C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 37, 28)) + + if (typeof y == 'string') { +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) + + y; // (T extends C ? number : string) & string +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) + } + else { + y; // T extends C ? number : string +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) + } + const newY: string | number = y; +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 69, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) + + newY; // string | number +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 69, 9)) +} + +function test4(y: T extends C ? string : number) { +>test4 : Symbol(test4, Decl(distributiveConditionalTypeConstraints.ts, 71, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 73, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 73, 15)) +>C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 37, 28)) + + if (typeof y == 'string') { +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) + + y; // (T extends C ? string : number) & string +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) + } + else { + y; // T extends C ? string : number +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) + } + const newY: string | number = y; +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 80, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) + + newY; // string | number +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 80, 9)) +} + diff --git a/tests/baselines/reference/distributiveConditionalTypeConstraints.types b/tests/baselines/reference/distributiveConditionalTypeConstraints.types new file mode 100644 index 0000000000000..8793a421c9782 --- /dev/null +++ b/tests/baselines/reference/distributiveConditionalTypeConstraints.types @@ -0,0 +1,202 @@ +//// [tests/cases/compiler/distributiveConditionalTypeConstraints.ts] //// + +=== distributiveConditionalTypeConstraints.ts === +type IsArray = T extends unknown[] ? true : false; +>IsArray : IsArray +>true : true +>false : false + +function f1(x: IsArray) { +>f1 : (x: IsArray) => void +>x : IsArray + + let t: true = x; // Error +>t : true +>true : true +>x : boolean + + let f: false = x; // Error +>f : false +>false : false +>x : boolean +} + +function f2(x: IsArray) { +>f2 : (x: IsArray) => void +>x : IsArray + + let t: true = x; +>t : true +>true : true +>x : IsArray + + let f: false = x; // Error +>f : false +>false : false +>x : IsArray +} + +function f3(x: IsArray) { +>f3 : (x: IsArray) => void +>x : IsArray + + let t: true = x; +>t : true +>true : true +>x : IsArray + + let f: false = x; // Error +>f : false +>false : false +>x : IsArray +} + +function f4(x: IsArray) { +>f4 : (x: IsArray) => void +>x : IsArray + + let t: true = x; // Error +>t : true +>true : true +>x : IsArray + + let f: false = x; +>f : false +>false : false +>x : IsArray +} + +type ZeroOf = +>ZeroOf : ZeroOf + + T extends null ? null : + T extends undefined ? undefined : + T extends string ? "" : + T extends number ? 0 : + T extends boolean ? false : +>false : false + + never; + +function f10(x: ZeroOf) { +>f10 : (x: ZeroOf) => void +>x : ZeroOf + + let t: "" | 0 | false = x; +>t : false | "" | 0 +>false : false +>x : false | "" | 0 +} + +// Modified repro from #30152 + +interface A { foo(): void; } +>foo : () => void + +interface B { bar(): void; } +>bar : () => void + +interface C { foo(): void, bar(): void } +>foo : () => void +>bar : () => void + +function test1(y: T extends B ? number : string) { +>test1 : (y: T extends B ? number : string) => void +>y : T extends B ? number : string + + if (typeof y == 'string') { +>typeof y == 'string' : boolean +>typeof y : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>y : T extends B ? number : string +>'string' : "string" + + y; // T extends B ? number : string +>y : T extends B ? number : string + } + else { + y; // never +>y : never + } + const newY: string | number = y; +>newY : string | number +>y : T extends B ? number : string + + newY; // string +>newY : string +} + +function test2(y: T extends B ? string : number) { +>test2 : (y: T extends B ? string : number) => void +>y : T extends B ? string : number + + if (typeof y == 'string') { +>typeof y == 'string' : boolean +>typeof y : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>y : T extends B ? string : number +>'string' : "string" + + y; // never +>y : never + } + else { + y; // T extends B ? string : number +>y : T extends B ? string : number + } + const newY: string | number = y; +>newY : string | number +>y : T extends B ? string : number + + newY; // number +>newY : number +} + +function test3(y: T extends C ? number : string) { +>test3 : (y: T extends C ? number : string) => void +>y : T extends C ? number : string + + if (typeof y == 'string') { +>typeof y == 'string' : boolean +>typeof y : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>y : T extends C ? number : string +>'string' : "string" + + y; // (T extends C ? number : string) & string +>y : (T extends C ? number : string) & string + } + else { + y; // T extends C ? number : string +>y : T extends C ? number : string + } + const newY: string | number = y; +>newY : string | number +>y : string | number + + newY; // string | number +>newY : string | number +} + +function test4(y: T extends C ? string : number) { +>test4 : (y: T extends C ? string : number) => void +>y : T extends C ? string : number + + if (typeof y == 'string') { +>typeof y == 'string' : boolean +>typeof y : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>y : T extends C ? string : number +>'string' : "string" + + y; // (T extends C ? string : number) & string +>y : (T extends C ? string : number) & string + } + else { + y; // T extends C ? string : number +>y : T extends C ? string : number + } + const newY: string | number = y; +>newY : string | number +>y : string | number + + newY; // string | number +>newY : string | number +} + diff --git a/tests/cases/compiler/distributiveConditionalTypeConstraints.ts b/tests/cases/compiler/distributiveConditionalTypeConstraints.ts new file mode 100644 index 0000000000000..82366a73c59ef --- /dev/null +++ b/tests/cases/compiler/distributiveConditionalTypeConstraints.ts @@ -0,0 +1,86 @@ +// @strict: true +// @noEmit: true + +type IsArray = T extends unknown[] ? true : false; + +function f1(x: IsArray) { + let t: true = x; // Error + let f: false = x; // Error +} + +function f2(x: IsArray) { + let t: true = x; + let f: false = x; // Error +} + +function f3(x: IsArray) { + let t: true = x; + let f: false = x; // Error +} + +function f4(x: IsArray) { + let t: true = x; // Error + let f: false = x; +} + +type ZeroOf = + T extends null ? null : + T extends undefined ? undefined : + T extends string ? "" : + T extends number ? 0 : + T extends boolean ? false : + never; + +function f10(x: ZeroOf) { + let t: "" | 0 | false = x; +} + +// Modified repro from #30152 + +interface A { foo(): void; } +interface B { bar(): void; } +interface C { foo(): void, bar(): void } + +function test1(y: T extends B ? number : string) { + if (typeof y == 'string') { + y; // T extends B ? number : string + } + else { + y; // never + } + const newY: string | number = y; + newY; // string +} + +function test2(y: T extends B ? string : number) { + if (typeof y == 'string') { + y; // never + } + else { + y; // T extends B ? string : number + } + const newY: string | number = y; + newY; // number +} + +function test3(y: T extends C ? number : string) { + if (typeof y == 'string') { + y; // (T extends C ? number : string) & string + } + else { + y; // T extends C ? number : string + } + const newY: string | number = y; + newY; // string | number +} + +function test4(y: T extends C ? string : number) { + if (typeof y == 'string') { + y; // (T extends C ? string : number) & string + } + else { + y; // T extends C ? string : number + } + const newY: string | number = y; + newY; // string | number +} From c7613d6b61978c600a22d611934eeb460e6ced5f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 6 Oct 2023 13:21:29 -0700 Subject: [PATCH 6/9] Use reverse assignable check instead of comparable check --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0da5650397157..a41ae603001ae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18323,7 +18323,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // then no instantiations will be and we can just return the false branch type. if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (checkType.flags & TypeFlags.Any || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) { // Return union of trueType and falseType for 'any' since it matches anything - if (checkType.flags & TypeFlags.Any || forConstraint && areTypesComparable(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType))) { + if (checkType.flags & TypeFlags.Any || forConstraint && isTypeAssignableTo(getPermissiveInstantiation(inferredExtendsType), getPermissiveInstantiation(checkType))) { (extraTypes || (extraTypes = [])).push(instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper)); } // If falseType is an immediately nested conditional type that isn't distributive or has an From f64e34c0c7219a730710983b9b532b880e76fc66 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 7 Oct 2023 08:15:09 -0700 Subject: [PATCH 7/9] Distribute over unions in reverse assignability check --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a41ae603001ae..03125ae21e560 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18323,7 +18323,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // then no instantiations will be and we can just return the false branch type. if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (checkType.flags & TypeFlags.Any || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) { // Return union of trueType and falseType for 'any' since it matches anything - if (checkType.flags & TypeFlags.Any || forConstraint && isTypeAssignableTo(getPermissiveInstantiation(inferredExtendsType), getPermissiveInstantiation(checkType))) { + if (checkType.flags & TypeFlags.Any || forConstraint && someType(getPermissiveInstantiation(inferredExtendsType), t => isTypeAssignableTo(t, getPermissiveInstantiation(checkType)))) { (extraTypes || (extraTypes = [])).push(instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper)); } // If falseType is an immediately nested conditional type that isn't distributive or has an From 1f0688704923aab160bc8472b82b9e8314ba9508 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 7 Oct 2023 08:18:46 -0700 Subject: [PATCH 8/9] Add test --- ...utiveConditionalTypeConstraints.errors.txt | 11 +- ...ributiveConditionalTypeConstraints.symbols | 127 ++++++++++-------- ...stributiveConditionalTypeConstraints.types | 15 +++ .../distributiveConditionalTypeConstraints.ts | 6 + 4 files changed, 103 insertions(+), 56 deletions(-) diff --git a/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt b/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt index 2b455f4e2eebd..dad1774d205f6 100644 --- a/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt +++ b/tests/baselines/reference/distributiveConditionalTypeConstraints.errors.txt @@ -6,9 +6,10 @@ distributiveConditionalTypeConstraints.ts(15,9): error TS2322: Type 'IsArray' Type 'true' is not assignable to type 'false'. distributiveConditionalTypeConstraints.ts(19,9): error TS2322: Type 'IsArray' is not assignable to type 'true'. Type 'false' is not assignable to type 'true'. +distributiveConditionalTypeConstraints.ts(38,9): error TS2322: Type 'boolean' is not assignable to type 'false'. -==== distributiveConditionalTypeConstraints.ts (5 errors) ==== +==== distributiveConditionalTypeConstraints.ts (6 errors) ==== type IsArray = T extends unknown[] ? true : false; function f1(x: IsArray) { @@ -56,6 +57,14 @@ distributiveConditionalTypeConstraints.ts(19,9): error TS2322: Type 'IsArray' let t: "" | 0 | false = x; } + type Foo = T extends "abc" | 42 ? true : false; + + function f20(x: Foo) { + let t: false = x; // Error + ~ +!!! error TS2322: Type 'boolean' is not assignable to type 'false'. + } + // Modified repro from #30152 interface A { foo(): void; } diff --git a/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols b/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols index 762237abde362..a94195dd0742d 100644 --- a/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols +++ b/tests/baselines/reference/distributiveConditionalTypeConstraints.symbols @@ -104,122 +104,139 @@ function f10(x: ZeroOf) { >x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 30, 27)) } +type Foo = T extends "abc" | 42 ? true : false; +>Foo : Symbol(Foo, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 34, 9)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 34, 9)) + +function f20(x: Foo) { +>f20 : Symbol(f20, Decl(distributiveConditionalTypeConstraints.ts, 34, 50)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 36, 13)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 36, 31)) +>Foo : Symbol(Foo, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 36, 13)) + + let t: false = x; // Error +>t : Symbol(t, Decl(distributiveConditionalTypeConstraints.ts, 37, 7)) +>x : Symbol(x, Decl(distributiveConditionalTypeConstraints.ts, 36, 31)) +} + // Modified repro from #30152 interface A { foo(): void; } ->A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) ->foo : Symbol(A.foo, Decl(distributiveConditionalTypeConstraints.ts, 36, 13)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 38, 1)) +>foo : Symbol(A.foo, Decl(distributiveConditionalTypeConstraints.ts, 42, 13)) interface B { bar(): void; } ->B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 36, 28)) ->bar : Symbol(B.bar, Decl(distributiveConditionalTypeConstraints.ts, 37, 13)) +>B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 42, 28)) +>bar : Symbol(B.bar, Decl(distributiveConditionalTypeConstraints.ts, 43, 13)) interface C { foo(): void, bar(): void } ->C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 37, 28)) ->foo : Symbol(C.foo, Decl(distributiveConditionalTypeConstraints.ts, 38, 13)) ->bar : Symbol(C.bar, Decl(distributiveConditionalTypeConstraints.ts, 38, 26)) +>C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 43, 28)) +>foo : Symbol(C.foo, Decl(distributiveConditionalTypeConstraints.ts, 44, 13)) +>bar : Symbol(C.bar, Decl(distributiveConditionalTypeConstraints.ts, 44, 26)) function test1(y: T extends B ? number : string) { ->test1 : Symbol(test1, Decl(distributiveConditionalTypeConstraints.ts, 38, 40)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 40, 15)) ->A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 40, 15)) ->B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 36, 28)) +>test1 : Symbol(test1, Decl(distributiveConditionalTypeConstraints.ts, 44, 40)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 46, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 38, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 46, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 46, 15)) +>B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 42, 28)) if (typeof y == 'string') { ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 46, 28)) y; // T extends B ? number : string ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 46, 28)) } else { y; // never ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 46, 28)) } const newY: string | number = y; ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 47, 9)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 40, 28)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 53, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 46, 28)) newY; // string ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 47, 9)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 53, 9)) } function test2(y: T extends B ? string : number) { ->test2 : Symbol(test2, Decl(distributiveConditionalTypeConstraints.ts, 49, 1)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 51, 15)) ->A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 51, 15)) ->B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 36, 28)) +>test2 : Symbol(test2, Decl(distributiveConditionalTypeConstraints.ts, 55, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 57, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 38, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 57, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 57, 15)) +>B : Symbol(B, Decl(distributiveConditionalTypeConstraints.ts, 42, 28)) if (typeof y == 'string') { ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 57, 28)) y; // never ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 57, 28)) } else { y; // T extends B ? string : number ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 57, 28)) } const newY: string | number = y; ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 58, 9)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 51, 28)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 64, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 57, 28)) newY; // number ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 58, 9)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 64, 9)) } function test3(y: T extends C ? number : string) { ->test3 : Symbol(test3, Decl(distributiveConditionalTypeConstraints.ts, 60, 1)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 62, 15)) ->A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 62, 15)) ->C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 37, 28)) +>test3 : Symbol(test3, Decl(distributiveConditionalTypeConstraints.ts, 66, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 68, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 38, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 68, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 68, 15)) +>C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 43, 28)) if (typeof y == 'string') { ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 68, 28)) y; // (T extends C ? number : string) & string ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 68, 28)) } else { y; // T extends C ? number : string ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 68, 28)) } const newY: string | number = y; ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 69, 9)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 62, 28)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 75, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 68, 28)) newY; // string | number ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 69, 9)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 75, 9)) } function test4(y: T extends C ? string : number) { ->test4 : Symbol(test4, Decl(distributiveConditionalTypeConstraints.ts, 71, 1)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 73, 15)) ->A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 32, 1)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) ->T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 73, 15)) ->C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 37, 28)) +>test4 : Symbol(test4, Decl(distributiveConditionalTypeConstraints.ts, 77, 1)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 79, 15)) +>A : Symbol(A, Decl(distributiveConditionalTypeConstraints.ts, 38, 1)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 79, 28)) +>T : Symbol(T, Decl(distributiveConditionalTypeConstraints.ts, 79, 15)) +>C : Symbol(C, Decl(distributiveConditionalTypeConstraints.ts, 43, 28)) if (typeof y == 'string') { ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 79, 28)) y; // (T extends C ? string : number) & string ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 79, 28)) } else { y; // T extends C ? string : number ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 79, 28)) } const newY: string | number = y; ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 80, 9)) ->y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 73, 28)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 86, 9)) +>y : Symbol(y, Decl(distributiveConditionalTypeConstraints.ts, 79, 28)) newY; // string | number ->newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 80, 9)) +>newY : Symbol(newY, Decl(distributiveConditionalTypeConstraints.ts, 86, 9)) } diff --git a/tests/baselines/reference/distributiveConditionalTypeConstraints.types b/tests/baselines/reference/distributiveConditionalTypeConstraints.types index 8793a421c9782..7cbcc3a69bb62 100644 --- a/tests/baselines/reference/distributiveConditionalTypeConstraints.types +++ b/tests/baselines/reference/distributiveConditionalTypeConstraints.types @@ -88,6 +88,21 @@ function f10(x: ZeroOf) { >x : false | "" | 0 } +type Foo = T extends "abc" | 42 ? true : false; +>Foo : Foo +>true : true +>false : false + +function f20(x: Foo) { +>f20 : (x: Foo) => void +>x : Foo + + let t: false = x; // Error +>t : false +>false : false +>x : boolean +} + // Modified repro from #30152 interface A { foo(): void; } diff --git a/tests/cases/compiler/distributiveConditionalTypeConstraints.ts b/tests/cases/compiler/distributiveConditionalTypeConstraints.ts index 82366a73c59ef..265e6d12c74ec 100644 --- a/tests/cases/compiler/distributiveConditionalTypeConstraints.ts +++ b/tests/cases/compiler/distributiveConditionalTypeConstraints.ts @@ -35,6 +35,12 @@ function f10(x: ZeroOf) { let t: "" | 0 | false = x; } +type Foo = T extends "abc" | 42 ? true : false; + +function f20(x: Foo) { + let t: false = x; // Error +} + // Modified repro from #30152 interface A { foo(): void; } From eb3e4b408b6f211e9f2e9598cf4d5c607f833cb5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Oct 2023 07:49:50 -0700 Subject: [PATCH 9/9] Exclude never types from check and add more comments --- src/compiler/checker.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 03125ae21e560..5056773c655f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18322,8 +18322,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // possible (the wildcard type is assignable to and from all types). If those are not related, // then no instantiations will be and we can just return the false branch type. if (!(inferredExtendsType.flags & TypeFlags.AnyOrUnknown) && (checkType.flags & TypeFlags.Any || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) { - // Return union of trueType and falseType for 'any' since it matches anything - if (checkType.flags & TypeFlags.Any || forConstraint && someType(getPermissiveInstantiation(inferredExtendsType), t => isTypeAssignableTo(t, getPermissiveInstantiation(checkType)))) { + // Return union of trueType and falseType for 'any' since it matches anything. Furthermore, for a + // distributive conditional type applied to the constraint of a type variable, include trueType if + // there are possible values of the check type that are also possible values of the extends type. + // We use a reverse assignability check as it is less expensive than the comparable relationship + // and avoids false positives of a non-empty intersection check. + if (checkType.flags & TypeFlags.Any || forConstraint && !(inferredExtendsType.flags & TypeFlags.Never) && someType(getPermissiveInstantiation(inferredExtendsType), t => isTypeAssignableTo(t, getPermissiveInstantiation(checkType)))) { (extraTypes || (extraTypes = [])).push(instantiateType(getTypeFromTypeNode(root.node.trueType), combinedMapper || mapper)); } // If falseType is an immediately nested conditional type that isn't distributive or has an