gvergnaud / ts-pattern

🎨 The exhaustive Pattern Matching library for TypeScript, with smart type inference.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Seemingly incorrect tuple maching types

rijenkii opened this issue · comments

Describe the bug
I was trying to match an array of unknown size, and execute functions:

  • a if arrays type is [],
  • b if arrays type is [string],
  • c if arrays type is [string, ...string[]].

I've tried doing it like this:

import { match, P } from "ts-pattern";

const array = ["1", "2", "3"] as readonly string[];

function a(_: readonly []) {}
function b(_: readonly [string]) {}
function c(_: readonly [string, ...string[]]) {}

match(array)
  .with([], a)
  .with([P.string], b)
  .with([P.string, ...P.string], c);

However I have noticed that when swapping functions in with calls, no typescript errors are produced, i.e. these all are correct according to the typechecker:

match(array).with([], a);
match(array).with([], b);
match(array).with([], c);
match(array).with([P.string], a);
match(array).with([P.string], b);
match(array).with([P.string], c);
match(array).with([P.string, ...P.string], a);
match(array).with([P.string, ...P.string], b);
match(array).with([P.string, ...P.string], c);

TypeScript sandbox with a minimal reproduction case

https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true&useDefineForClassFields=true&noLib=true&noStrictGenericChecks=true&target=9&suppressImplicitAnyIndexErrors=false&noImplicitOverride=false&noFallthroughCasesInSwitch=false&pretty=false&noErrorTruncation=false&preserveWatchOutput=false&inlineSources=false&stripInternal=false&preserveValueImports=false&isolatedModules=false&allowSyntheticDefaultImports=false&verbatimModuleSyntax=false#code/JYWwDg9gTgLgBAbziAhjAxgCwDRwApwC+cAZlBCHAEQwDOAtGGjAKZQB2VA3AFA-oR2teCihQUATzgBeOAG0qARiq4qAJhXUAzFQC6cFLThQWKACaCANlOFRg7AOZzdvHiQCu7dDGCCDACgB9AC5jUwt2a3ldAEpEQjdPb192OAAjINCTcyspOVt7B1j4xK8fP3RMsJzIvILHXAA6ZvqnXWKEBJ5UDEx-UXEJGJ44OEaAd2AYPudcFGHRiamZvEbW3Vw0hbHJ6f85Vdam5sOYO0cNuHQY1x6sfrFJGKW92YMb7rR7gaeXmcutrw7n0fkM-vtLtcgV8QY8wbsVmszoVLvNob0HoNngj9qdzkVNh9gZjfjiDkj8ZCiTCSfDlriKYVjo08Si5tSMaDsfTyUcxidGRdCejvnDua9WQ1+SzBQSrh8gA

Versions

  • TypeScript version: 5.2.2
  • ts-pattern version: 5.0.5
  • environment: N/A?

It's because you've disabled strict generic checks.

Removing that setting fixes it, mostly: Playground.

There are more issues...

The rest pattern is incorrect/invalid. You need [P.string, ...P.array(P.string)] instead of [P.string, ...P.string].
I removed the other config options from your playground and that is now correctly an error.
And array is no longer always typed as {}...
Everything then seems as expected.