Skip to content

Commit

Permalink
fix(P.infer): Fix inference of array containing tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
gvergnaud committed Jul 13, 2023
1 parent 30ba1f0 commit c52af6a
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 16 deletions.
6 changes: 4 additions & 2 deletions src/types/InvertPattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
Call,
Fn,
ReadonlyArrayValue,
ExtractWithDefault,
WithDefault,
} from './helpers';
import type { Matcher, Pattern, Override, AnyMatcher } from './Pattern';
Expand Down Expand Up @@ -141,7 +140,10 @@ type InvertPatternInternal<p, input> = 0 extends 1 & p
: p extends Primitives
? p
: p extends readonly any[]
? InvertArrayPattern<p, ExtractWithDefault<input, readonly any[], unknown[]>>
? InvertArrayPattern<
p,
WithDefault<Extract<input, readonly any[]>, unknown[]>
>
: IsPlainObject<p> extends true
? OptionalKeys<p> extends infer optKeys
? [optKeys] extends [never]
Expand Down
2 changes: 0 additions & 2 deletions src/types/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ export type IntersectObjects<a> = (

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

export type ExtractWithDefault<a, b, def> = a extends b ? a : def;

export type IsLiteral<a> = [a] extends [null | undefined]
? true
: [a] extends [string]
Expand Down
25 changes: 25 additions & 0 deletions tests/infer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { P } from '../src';
import { Equal, Expect } from '../src/types/helpers';

describe('P.infer', () => {
describe('array', () => {
it('should correctly narrow types of arrays containing tuples', () => {
const QuizValue = P.union('initial', 'correct', 'incorrect');
const QuizState = {
answerEntries: P.array([P.string, QuizValue]),
appendOnlyAnswerEntries: P.array([P.string, P.array(QuizValue)]),
};

type QuizValue = P.infer<typeof QuizValue>;
type expected1 = 'initial' | 'correct' | 'incorrect';
type test1 = Expect<Equal<QuizValue, expected1>>;

type QuizState = P.infer<typeof QuizState>;
type expected2 = {
answerEntries: [string, QuizValue][];
appendOnlyAnswerEntries: [string, QuizValue[]][];
};
type test2 = Expect<Equal<QuizState, expected2>>;
});
});
});
13 changes: 1 addition & 12 deletions tests/readonly.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
import { match } from '../src';
import { DeepExclude } from '../src/types/DeepExclude';
import {
InvertPattern,
InvertPatternForExclude,
} from '../src/types/InvertPattern';
import { MatchedValue } from '../src/types/Pattern';
import {
Equal,
Expect,
ExtractWithDefault,
IsReadonlyArray,
} from '../src/types/helpers';
import { Equal, Expect } from '../src/types/helpers';

describe('readonly', () => {
describe('exhaustive', () => {
Expand Down

0 comments on commit c52af6a

Please sign in to comment.