✨ Add primitive union pattern matchers
Curried matchers over string|number literal unions in four variants (exhaustive/partial x strict/widened return inference), per the header matrix in src/primitive.ts. - Adds type-fest for Simplify/ValueOf. - Deliberate oxlint escape hatches (as any dispatch) until a cast-free formulation lands; see the file comments.
This commit is contained in:
1 parent
1e13917cbe
commit
40bf652b97
3 files changed
+94
No files matched your search
Generated
+30
@@ -8,6 +8,9 @@
|
||||
"name": "tiny-pattern-ts",
|
||||
"version": "0.1.8",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"type-fest": "^5.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.18.5",
|
||||
"@runwisp/pubv": "^1.5.1",
|
||||
@@ -4622,6 +4625,18 @@
|
||||
"url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/tagged-tag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz",
|
||||
"integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz",
|
||||
@@ -4705,6 +4720,21 @@
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "5.9.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.9.0.tgz",
|
||||
"integrity": "sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==",
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"dependencies": {
|
||||
"tagged-tag": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz",
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
"setup": "npm run setup:git-commit-message",
|
||||
"setup:git-commit-message": "git config commit.template commit-message-template"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": "^5.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.18.5",
|
||||
"@runwisp/pubv": "^1.5.1",
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import type { Simplify, ValueOf } from "type-fest";
|
||||
|
||||
type UnaryFn<T, R> = (shape: T) => R;
|
||||
|
||||
// ============================================================================
|
||||
// ✔️ Exhaustive
|
||||
// ❌ ReturnsStrict
|
||||
// ============================================================================
|
||||
type PatternPrimitiveUnion<R, T extends string | number> = {
|
||||
[K in T]: UnaryFn<K, R>;
|
||||
};
|
||||
|
||||
type PatternReturns<
|
||||
P extends Record<string | number, UnaryFn<never, unknown>>,
|
||||
> = ReturnType<ValueOf<P>>;
|
||||
|
||||
export const getPrimitiveUnionMatcherW: <T extends string | number>() => <
|
||||
P extends PatternPrimitiveUnion<unknown, T>,
|
||||
>(
|
||||
pattern: Simplify<P>,
|
||||
) => UnaryFn<T, PatternReturns<P>> = () => (pattern) => (shape) =>
|
||||
// oxlint-disable-next-line typescript/no-explicit-any typescript/no-unsafe-type-assertion
|
||||
(pattern[shape] as any)(shape);
|
||||
|
||||
// ============================================================================
|
||||
// ✔️ Exhaustive
|
||||
// ✔️ ReturnsStrict
|
||||
// ============================================================================
|
||||
export const getPrimitiveUnionMatcher: <T extends string | number>() => <R>(
|
||||
pattern: Simplify<PatternPrimitiveUnion<R, T>>,
|
||||
) => UnaryFn<T, R> = getPrimitiveUnionMatcherW;
|
||||
|
||||
// ============================================================================
|
||||
// ❌ Exhaustive
|
||||
// ✔️ ReturnsStrict
|
||||
// ============================================================================
|
||||
type PatternPrimitiveUnionPartial<R, T extends string | number> =
|
||||
| PatternPrimitiveUnion<R, T>
|
||||
| (Partial<PatternPrimitiveUnion<R, T>> & {
|
||||
_: UnaryFn<T, R>;
|
||||
});
|
||||
|
||||
export const getPrimitiveUnionMatcherPartial: <T extends string | number>() => <
|
||||
R,
|
||||
>(
|
||||
pattern: Simplify<PatternPrimitiveUnionPartial<R, T>>,
|
||||
) => UnaryFn<T, R> = () => (pattern) => (shape) =>
|
||||
// oxlint-disable-next-line typescript/no-explicit-any typescript/no-unsafe-type-assertion
|
||||
(pattern[shape] ?? (pattern as any)["_"])(shape);
|
||||
|
||||
// ============================================================================
|
||||
// ❌ Exhaustive
|
||||
// ❌ ReturnsStrict
|
||||
// ============================================================================
|
||||
export const getPrimitiveUnionMatcherPartialW: <
|
||||
T extends string | number,
|
||||
>() => <P extends PatternPrimitiveUnionPartial<unknown, T>>(
|
||||
pattern: Simplify<P>,
|
||||
|
||||
// oxlint-disable-next-line typescript/no-explicit-any typescript/no-unsafe-type-assertion
|
||||
) => UnaryFn<T, PatternReturns<P>> = getPrimitiveUnionMatcherPartial as any;
|
||||
Reference in new issue
Block a user