Skip to content

Commit c52af6a

Browse files
committed
fix(P.infer): Fix inference of array containing tuples
1 parent 30ba1f0 commit c52af6a

4 files changed

Lines changed: 30 additions & 16 deletions

File tree

src/types/InvertPattern.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
Call,
2121
Fn,
2222
ReadonlyArrayValue,
23-
ExtractWithDefault,
2423
WithDefault,
2524
} from './helpers';
2625
import type { Matcher, Pattern, Override, AnyMatcher } from './Pattern';
@@ -141,7 +140,10 @@ type InvertPatternInternal<p, input> = 0 extends 1 & p
141140
: p extends Primitives
142141
? p
143142
: p extends readonly any[]
144-
? InvertArrayPattern<p, ExtractWithDefault<input, readonly any[], unknown[]>>
143+
? InvertArrayPattern<
144+
p,
145+
WithDefault<Extract<input, readonly any[]>, unknown[]>
146+
>
145147
: IsPlainObject<p> extends true
146148
? OptionalKeys<p> extends infer optKeys
147149
? [optKeys] extends [never]

src/types/helpers.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ export type IntersectObjects<a> = (
155155

156156
export type WithDefault<a, def> = [a] extends [never] ? def : a;
157157

158-
export type ExtractWithDefault<a, b, def> = a extends b ? a : def;
159-
160158
export type IsLiteral<a> = [a] extends [null | undefined]
161159
? true
162160
: [a] extends [string]

tests/infer.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { P } from '../src';
2+
import { Equal, Expect } from '../src/types/helpers';
3+
4+
describe('P.infer', () => {
5+
describe('array', () => {
6+
it('should correctly narrow types of arrays containing tuples', () => {
7+
const QuizValue = P.union('initial', 'correct', 'incorrect');
8+
const QuizState = {
9+
answerEntries: P.array([P.string, QuizValue]),
10+
appendOnlyAnswerEntries: P.array([P.string, P.array(QuizValue)]),
11+
};
12+
13+
type QuizValue = P.infer<typeof QuizValue>;
14+
type expected1 = 'initial' | 'correct' | 'incorrect';
15+
type test1 = Expect<Equal<QuizValue, expected1>>;
16+
17+
type QuizState = P.infer<typeof QuizState>;
18+
type expected2 = {
19+
answerEntries: [string, QuizValue][];
20+
appendOnlyAnswerEntries: [string, QuizValue[]][];
21+
};
22+
type test2 = Expect<Equal<QuizState, expected2>>;
23+
});
24+
});
25+
});

tests/readonly.test.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
import { match } from '../src';
2-
import { DeepExclude } from '../src/types/DeepExclude';
3-
import {
4-
InvertPattern,
5-
InvertPatternForExclude,
6-
} from '../src/types/InvertPattern';
7-
import { MatchedValue } from '../src/types/Pattern';
8-
import {
9-
Equal,
10-
Expect,
11-
ExtractWithDefault,
12-
IsReadonlyArray,
13-
} from '../src/types/helpers';
2+
import { Equal, Expect } from '../src/types/helpers';
143

154
describe('readonly', () => {
165
describe('exhaustive', () => {

0 commit comments

Comments
 (0)