You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
IsLiteral: Adding strict options and Fixing unpredictable behaviors of IsStringLiteral returning boolean for unions and IsNumericLiteral returning false for numeric unions
- Matching `IsStringLiteral` behavior to the other is*Literals when dealing with unions of different types return boolean, now return false.
- Fixing `IsNumericLiteral` return false for numeric union like (1 | 1n), now return true.
- Adding `strict` option to control the behavior of `IsStringLiteral` against infinite signature types.
* Checks if one type extends another. Note: this is not quite the same as `Left extends Right` because:
19
+
* 1. If either type is `never`, the result is `true` iff the other type is also `never`.
20
+
* 2. Types are wrapped in a 1-tuple so that union types are not distributed - instead we consider `string | number` to _not_ extend `number`. If we used `Left extends Right` directly you would get `Extends<string | number, number>` => `false | true` => `boolean`.
Returns a boolean for whether the given type `T` is the specified `LiteralType`.
@@ -24,11 +38,10 @@ LiteralCheck<1, string>
24
38
typeLiteralCheck<T,LiteralTypeextendsPrimitive>=(
25
39
IsNever<T>extendsfalse// Must be wider than `never`
26
40
? [T]extends[LiteralType& infer U]// Remove any branding
27
-
? [U]extends[LiteralType]// Must be narrower than `LiteralType`
28
-
? [LiteralType]extends[U]// Cannot be wider than `LiteralType`
29
-
? false
30
-
: true
31
-
: false
41
+
? And<
42
+
Extends<U,LiteralType>,// Must be narrower than `LiteralType`
43
+
Not<Extends<LiteralType,U>>// Cannot be wider than `LiteralType`
44
+
>
32
45
: false
33
46
: false
34
47
);
@@ -52,9 +65,10 @@ type LiteralChecks<T, LiteralUnionType> = (
52
65
// Conditional type to force union distribution.
53
66
// If `T` is none of the literal types in the union `LiteralUnionType`, then `LiteralCheck<T, LiteralType>` will evaluate to `false` for the whole union.
54
67
// If `T` is one of the literal types in the union, it will evaluate to `boolean` (i.e. `true | false`)
55
-
IsNotFalse<LiteralUnionTypeextendsPrimitive
56
-
? LiteralCheck<T,LiteralUnionType>
57
-
: never
68
+
IsNotFalse<
69
+
LiteralUnionTypeextendsPrimitive
70
+
? LiteralCheck<T,LiteralUnionType>
71
+
: never
58
72
>
59
73
);
60
74
@@ -111,21 +125,30 @@ type L2 = Length<`${number}`>;
? CollapseLiterals<TextendsTagContainer<any> ? UnwrapTagged<T> : T>extends infer Type
136
+
? ResolvedOptions['strict']extendstrue
137
+
? IsTrue<_IsStringLiteral<Type>>
138
+
: LiteralCheck<Type,string>
139
+
: never
140
+
: false
141
+
: never
142
+
143
+
type_IsStringLiteral<S>=(
144
+
// If `T` is an infinite string type (e.g., `on${string}`), `Record<T, never>` produces an index signature,
145
+
// and since `{}` extends index signatures, the result becomes `false`.
146
+
Sextendsstring
147
+
? {}extendsRecord<S,never>
148
+
? false
149
+
: true
150
+
: false
151
+
);
129
152
130
153
/**
131
154
Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
0 commit comments