From 00e3926c48c050b4e859072f58e6189d05593054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 30 Aug 2022 17:55:17 +0200 Subject: [PATCH] Defer distributing index over generic object types --- src/compiler/checker.ts | 3 ++ ...tWithIndexSignatureWithNonNullable.symbols | 39 +++++++++++++++++++ ...intWithIndexSignatureWithNonNullable.types | 24 ++++++++++++ ...traintWithIndexSignatureWithNonNullable.ts | 16 ++++++++ 4 files changed, 82 insertions(+) create mode 100644 tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.symbols create mode 100644 tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.types create mode 100644 tests/cases/compiler/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 01fc87bae36a4..70daadb092357 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15903,6 +15903,9 @@ namespace ts { } function distributeIndexOverObjectType(objectType: Type, indexType: Type, writing: boolean) { + if (shouldDeferIndexType(objectType)) { + return; + } // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] diff --git a/tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.symbols b/tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.symbols new file mode 100644 index 0000000000000..c94bc76ef60a3 --- /dev/null +++ b/tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.symbols @@ -0,0 +1,39 @@ +=== tests/cases/compiler/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts === +interface StateSchema { +>StateSchema : Symbol(StateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 0, 0)) + + states?: { +>states : Symbol(StateSchema.states, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 0, 23)) + + [key: string]: StateSchema; +>key : Symbol(key, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 2, 5)) +>StateSchema : Symbol(StateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 0, 0)) + + }; +} + +declare class StateNode { +>StateNode : Symbol(StateNode, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 4, 1)) +>TStateSchema : Symbol(TStateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 6, 24)) +>StateSchema : Symbol(StateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 0, 0)) + + schema: TStateSchema; +>schema : Symbol(StateNode.schema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 6, 59)) +>TStateSchema : Symbol(TStateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 6, 24)) +} + +type StateNodesConfig = { +>StateNodesConfig : Symbol(StateNodesConfig, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 8, 1)) +>TStateSchema : Symbol(TStateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 10, 22)) +>StateSchema : Symbol(StateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 0, 0)) + + [K in keyof TStateSchema["states"]]: StateNode[K]>; +>K : Symbol(K, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 11, 3)) +>TStateSchema : Symbol(TStateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 10, 22)) +>StateNode : Symbol(StateNode, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 4, 1)) +>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --)) +>TStateSchema : Symbol(TStateSchema, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 10, 22)) +>K : Symbol(K, Decl(mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts, 11, 3)) + +}; + diff --git a/tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.types b/tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.types new file mode 100644 index 0000000000000..324becfe6b1cf --- /dev/null +++ b/tests/baselines/reference/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts === +interface StateSchema { + states?: { +>states : { [key: string]: StateSchema; } | undefined + + [key: string]: StateSchema; +>key : string + + }; +} + +declare class StateNode { +>StateNode : StateNode + + schema: TStateSchema; +>schema : TStateSchema +} + +type StateNodesConfig = { +>StateNodesConfig : StateNodesConfig + + [K in keyof TStateSchema["states"]]: StateNode[K]>; +}; + diff --git a/tests/cases/compiler/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts b/tests/cases/compiler/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts new file mode 100644 index 0000000000000..025170356f969 --- /dev/null +++ b/tests/cases/compiler/mappedTypeOverNullableConstraintWithIndexSignatureWithNonNullable.ts @@ -0,0 +1,16 @@ +// @noEmit: true +// @strict: true + +interface StateSchema { + states?: { + [key: string]: StateSchema; + }; +} + +declare class StateNode { + schema: TStateSchema; +} + +type StateNodesConfig = { + [K in keyof TStateSchema["states"]]: StateNode[K]>; +};