From 2fe8d2472891326e3006eddbab074d59f1f7027e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 15 Aug 2023 18:04:43 +0200 Subject: [PATCH 1/2] Add numeric constraints to type parameters of mapped types with narrowed down array constraints --- src/compiler/checker.ts | 2 +- .../numericStringLiteralTypes2.symbols | 76 +++++++++++++++++++ .../numericStringLiteralTypes2.types | 39 ++++++++++ .../literal/numericStringLiteralTypes2.ts | 25 ++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/numericStringLiteralTypes2.symbols create mode 100644 tests/baselines/reference/numericStringLiteralTypes2.types create mode 100644 tests/cases/conformance/types/literal/numericStringLiteralTypes2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 33441d618d79a..f624e985f0408 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15580,7 +15580,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) { const typeParameter = getHomomorphicTypeVariable(mappedType); if (typeParameter) { - const constraint = getConstraintOfTypeParameter(typeParameter); + const constraint = getConstraintOfTypeParameter(getConditionalFlowTypeOfType(typeParameter, parent)); if (constraint && everyType(constraint, isArrayOrTupleType)) { constraints = append(constraints, getUnionType([numberType, numericStringType])); } diff --git a/tests/baselines/reference/numericStringLiteralTypes2.symbols b/tests/baselines/reference/numericStringLiteralTypes2.symbols new file mode 100644 index 0000000000000..0be747245c215 --- /dev/null +++ b/tests/baselines/reference/numericStringLiteralTypes2.symbols @@ -0,0 +1,76 @@ +//// [tests/cases/conformance/types/literal/numericStringLiteralTypes2.ts] //// + +=== numericStringLiteralTypes2.ts === +// https://github.com/microsoft/TypeScript/issues/55383 + +type LiteralType = string | number | boolean; +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) + +type ValueGetter = () => ValueType; +>ValueGetter : Symbol(ValueGetter, Decl(numericStringLiteralTypes2.ts, 2, 45)) +>ValueType : Symbol(ValueType, Decl(numericStringLiteralTypes2.ts, 3, 17)) +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) +>ValueType : Symbol(ValueType, Decl(numericStringLiteralTypes2.ts, 3, 17)) + +type Schema = SchemaArray | SchemaObject | LiteralType; +>Schema : Symbol(Schema, Decl(numericStringLiteralTypes2.ts, 3, 80)) +>SchemaArray : Symbol(SchemaArray, Decl(numericStringLiteralTypes2.ts, 5, 55)) +>SchemaObject : Symbol(SchemaObject, Decl(numericStringLiteralTypes2.ts, 6, 67)) +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) + +type SchemaArray = Array; +>SchemaArray : Symbol(SchemaArray, Decl(numericStringLiteralTypes2.ts, 5, 55)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>SchemaObject : Symbol(SchemaObject, Decl(numericStringLiteralTypes2.ts, 6, 67)) +>SchemaArray : Symbol(SchemaArray, Decl(numericStringLiteralTypes2.ts, 5, 55)) +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) + +type SchemaObject = { +>SchemaObject : Symbol(SchemaObject, Decl(numericStringLiteralTypes2.ts, 6, 67)) + + [key: string]: SchemaObject | SchemaArray | LiteralType; +>key : Symbol(key, Decl(numericStringLiteralTypes2.ts, 8, 3)) +>SchemaObject : Symbol(SchemaObject, Decl(numericStringLiteralTypes2.ts, 6, 67)) +>SchemaArray : Symbol(SchemaArray, Decl(numericStringLiteralTypes2.ts, 5, 55)) +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) + +}; + +type InferValuesFromSchema = S extends LiteralType +>InferValuesFromSchema : Symbol(InferValuesFromSchema, Decl(numericStringLiteralTypes2.ts, 9, 2)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>Schema : Symbol(Schema, Decl(numericStringLiteralTypes2.ts, 3, 80)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>LiteralType : Symbol(LiteralType, Decl(numericStringLiteralTypes2.ts, 0, 0)) + + ? ValueGetter +>ValueGetter : Symbol(ValueGetter, Decl(numericStringLiteralTypes2.ts, 2, 45)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) + + : S extends SchemaArray +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>SchemaArray : Symbol(SchemaArray, Decl(numericStringLiteralTypes2.ts, 5, 55)) + + ? { + [K in keyof S]: InferValuesFromSchema; // `S[K]` should satisfy the required `Schema` constraint here +>K : Symbol(K, Decl(numericStringLiteralTypes2.ts, 15, 7)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>InferValuesFromSchema : Symbol(InferValuesFromSchema, Decl(numericStringLiteralTypes2.ts, 9, 2)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>K : Symbol(K, Decl(numericStringLiteralTypes2.ts, 15, 7)) + } + : S extends SchemaObject +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>SchemaObject : Symbol(SchemaObject, Decl(numericStringLiteralTypes2.ts, 6, 67)) + + ? { + [K in keyof S]: InferValuesFromSchema; +>K : Symbol(K, Decl(numericStringLiteralTypes2.ts, 19, 7)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>InferValuesFromSchema : Symbol(InferValuesFromSchema, Decl(numericStringLiteralTypes2.ts, 9, 2)) +>S : Symbol(S, Decl(numericStringLiteralTypes2.ts, 11, 27)) +>K : Symbol(K, Decl(numericStringLiteralTypes2.ts, 19, 7)) + } + : never; + diff --git a/tests/baselines/reference/numericStringLiteralTypes2.types b/tests/baselines/reference/numericStringLiteralTypes2.types new file mode 100644 index 0000000000000..a9b25df8fc76f --- /dev/null +++ b/tests/baselines/reference/numericStringLiteralTypes2.types @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/types/literal/numericStringLiteralTypes2.ts] //// + +=== numericStringLiteralTypes2.ts === +// https://github.com/microsoft/TypeScript/issues/55383 + +type LiteralType = string | number | boolean; +>LiteralType : string | number | boolean + +type ValueGetter = () => ValueType; +>ValueGetter : ValueGetter + +type Schema = SchemaArray | SchemaObject | LiteralType; +>Schema : LiteralType | SchemaArray | SchemaObject + +type SchemaArray = Array; +>SchemaArray : (LiteralType | SchemaArray | SchemaObject)[] + +type SchemaObject = { +>SchemaObject : { [key: string]: LiteralType | SchemaArray | SchemaObject; } + + [key: string]: SchemaObject | SchemaArray | LiteralType; +>key : string + +}; + +type InferValuesFromSchema = S extends LiteralType +>InferValuesFromSchema : InferValuesFromSchema + + ? ValueGetter + : S extends SchemaArray + ? { + [K in keyof S]: InferValuesFromSchema; // `S[K]` should satisfy the required `Schema` constraint here + } + : S extends SchemaObject + ? { + [K in keyof S]: InferValuesFromSchema; + } + : never; + diff --git a/tests/cases/conformance/types/literal/numericStringLiteralTypes2.ts b/tests/cases/conformance/types/literal/numericStringLiteralTypes2.ts new file mode 100644 index 0000000000000..32bf0bc4302bd --- /dev/null +++ b/tests/cases/conformance/types/literal/numericStringLiteralTypes2.ts @@ -0,0 +1,25 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/55383 + +type LiteralType = string | number | boolean; +type ValueGetter = () => ValueType; + +type Schema = SchemaArray | SchemaObject | LiteralType; +type SchemaArray = Array; +type SchemaObject = { + [key: string]: SchemaObject | SchemaArray | LiteralType; +}; + +type InferValuesFromSchema = S extends LiteralType + ? ValueGetter + : S extends SchemaArray + ? { + [K in keyof S]: InferValuesFromSchema; // `S[K]` should satisfy the required `Schema` constraint here + } + : S extends SchemaObject + ? { + [K in keyof S]: InferValuesFromSchema; + } + : never; From 8b45731af78d525e20fa2e7252767a71ef6a4753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 12 Jul 2024 23:14:25 +0200 Subject: [PATCH 2/2] update baselines --- tests/baselines/reference/deepComparisons.types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/deepComparisons.types b/tests/baselines/reference/deepComparisons.types index ce329516adba8..d803925f0834d 100644 --- a/tests/baselines/reference/deepComparisons.types +++ b/tests/baselines/reference/deepComparisons.types @@ -1,7 +1,7 @@ //// [tests/cases/compiler/deepComparisons.ts] //// === Performance Stats === -Type Count: 2,500 +Type Count: 1,000 Instantiation count: 2,500 === deepComparisons.ts ===