🐛 Infer strict return from the handler map
The fallback overload could not infer `R` from the handlers: `R` appeared only inside the `Exact` constraint, which is not an inference site, so with inferred handler params it collapsed to `unknown` and the matcher silently returned `UnaryFn<T, unknown>`. Adding `Partial<Handlers<T, R>>` to the handler parameter gives `R` an inference site, so the common return is inferred from the handlers and the fallback alike. Tests drop their explicit handler return annotations: real handlers are short and unannotated, and the common type is now inferred from them.
This commit is contained in:
1 parent
2d3577716d
commit
c7223dbe69
2 files changed
+14
-14
No files matched your search
+13
-13
@@ -22,11 +22,11 @@ test("getMatcher: exhaustive pattern infers one common return type", () => {
|
||||
|
||||
// Act
|
||||
const matcher = factory({
|
||||
a: (s): number => {
|
||||
a: (s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"a">();
|
||||
return 1;
|
||||
},
|
||||
b: (s): 1 | 2 => {
|
||||
b: (s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"b">();
|
||||
return 2;
|
||||
},
|
||||
@@ -69,19 +69,19 @@ test("getMatcher: dispatches on mixed string and numeric keys", () => {
|
||||
|
||||
// Act
|
||||
const matcher = factory({
|
||||
a: (s): number => {
|
||||
a: (s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"a">();
|
||||
return 1;
|
||||
},
|
||||
b: (s): 1 | 2 => {
|
||||
b: (s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"b">();
|
||||
return 2;
|
||||
},
|
||||
1: (n): number => {
|
||||
1: (n) => {
|
||||
expectTypeOf(n).toEqualTypeOf<1>();
|
||||
return 10;
|
||||
},
|
||||
2: (n): number => {
|
||||
2: (n) => {
|
||||
expectTypeOf(n).toEqualTypeOf<2>();
|
||||
return 20;
|
||||
},
|
||||
@@ -106,15 +106,15 @@ test("getMatcher: a `_` fallback receives the unhandled keys", () => {
|
||||
// Act
|
||||
const matcher = factory(
|
||||
{
|
||||
a: (s): 1 | 2 => {
|
||||
a: (s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"a">();
|
||||
return 1;
|
||||
return 1 as const;
|
||||
},
|
||||
},
|
||||
(s): 1 | 2 => {
|
||||
(s) => {
|
||||
// The fallback sees only the keys `a` did not handle.
|
||||
expectTypeOf(s).toEqualTypeOf<"b" | "c">();
|
||||
return 2;
|
||||
return 2 as const;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -134,16 +134,16 @@ test("getMatcher: a `_` fallback routes mixed string and numeric gaps", () => {
|
||||
// Act
|
||||
const matcher = factory(
|
||||
{
|
||||
a: (s): string => {
|
||||
a: (s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"a">();
|
||||
return "A";
|
||||
},
|
||||
1: (n): string => {
|
||||
1: (n) => {
|
||||
expectTypeOf(n).toEqualTypeOf<1>();
|
||||
return "one";
|
||||
},
|
||||
},
|
||||
(s): string => {
|
||||
(s) => {
|
||||
expectTypeOf(s).toEqualTypeOf<"b" | 2>();
|
||||
return "fallback";
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user