From d89a70978a69ce5ceae4ed659b8f69bbf3b2baa7 Mon Sep 17 00:00:00 2001 From: George Zhao Date: Tue, 2 Jul 2024 22:35:17 +1000 Subject: [PATCH] `Exact`: Fix support for `Date` in union (#902) --- source/exact.d.ts | 9 ++++----- test-d/exact.ts | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/source/exact.d.ts b/source/exact.d.ts index af54e9d46..3d8cdaf33 100644 --- a/source/exact.d.ts +++ b/source/exact.d.ts @@ -1,7 +1,7 @@ import type {ArrayElement, ObjectValue} from './internal'; -import type {Opaque, TagContainer} from './opaque'; import type {IsEqual} from './is-equal'; import type {KeysOfUnion} from './keys-of-union'; +import type {JsonObject} from './basic'; /** Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`. @@ -57,7 +57,6 @@ export type Exact = : ParameterType extends unknown[] ? Array, ArrayElement>> // In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray. : ParameterType extends readonly unknown[] ? ReadonlyArray, ArrayElement>> - // Leave tagged types as-is. We could try to make the untagged part Exact, and just leave the tag as-is, but that seems to create instanitation excessively deep errors. - : ParameterType extends TagContainer ? ParameterType - : ParameterType extends object ? ExactObject - : ParameterType; + // Only apply Exact for pure object types. For types from a class, leave it unchanged to TypeScript to handle. + : ParameterType extends JsonObject ? ExactObject + : ParameterType; diff --git a/test-d/exact.ts b/test-d/exact.ts index bd504260b..d345f9f32 100644 --- a/test-d/exact.ts +++ b/test-d/exact.ts @@ -450,3 +450,20 @@ import type {Exact, Opaque} from '../index'; }, }); } + +// Spec - special test case for Date type + union +// @see https://github.com/sindresorhus/type-fest/issues/896 +{ + type A = { + a: string; + b?: Date | null; + }; + + const function_ = >(arguments_: T) => arguments_; + + function_({a: 'a'}); + function_({a: 'a', b: new Date()}); + function_({a: 'a', b: new Date() as Date | null}); + // @ts-expect-error + function_({a: 'a', b: 1}); +}