@elliots/typical 0.2.5 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -8
- package/package.json +12 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Typical
|
|
2
2
|
|
|
3
|
-
Typical makes TypeScript type
|
|
3
|
+
Typical makes TypeScript type safe at runtime _with no changes to your code_.
|
|
4
4
|
|
|
5
5
|
It transforms your code to inject runtime validation based on your existing type annotations. With source maps, so errors point to the right lines in your original code.
|
|
6
6
|
|
|
@@ -38,13 +38,14 @@ const user = JSON.parse('{"name":"Alice","email":"not-an-email"}') as User;
|
|
|
38
38
|
|
|
39
39
|
Choose the integration that fits your workflow:
|
|
40
40
|
|
|
41
|
-
| Method | Best For | Package
|
|
42
|
-
| --------------------------------------------------------- | ------------------------------- |
|
|
43
|
-
| [ESM Loader](#nodejs-esm-loader) | Node.js scripts, development | `@elliots/typical`
|
|
44
|
-
| [ttsx](#ttsx-tsx-wrapper) | Quick scripts with tsx | `@elliots/typical` + `tsx`
|
|
45
|
-
| [Bun Plugin](#bun) | Bun projects | `@elliots/bun-plugin-typical`
|
|
46
|
-
| [
|
|
47
|
-
| [
|
|
41
|
+
| Method | Best For | Package |
|
|
42
|
+
| --------------------------------------------------------- | ------------------------------- | ------------------------------------ |
|
|
43
|
+
| [ESM Loader](#nodejs-esm-loader) | Node.js scripts, development | `@elliots/typical` |
|
|
44
|
+
| [ttsx](#ttsx-tsx-wrapper) | Quick scripts with tsx | `@elliots/typical` + `tsx` |
|
|
45
|
+
| [Bun Plugin](#bun) | Bun projects | `@elliots/bun-plugin-typical` |
|
|
46
|
+
| [React Native / Expo](#react-native--expo) | React Native apps | `@elliots/metro-transformer-typical` |
|
|
47
|
+
| [Vite/Webpack/etc](#bundlers-vite-webpack-rollup-esbuild) | Frontend apps, bundled projects | `@elliots/unplugin-typical` |
|
|
48
|
+
| [tsc Plugin](#typescript-compiler-tsc) | Pure TypeScript compilation | `@elliots/typical-tsc-plugin` |
|
|
48
49
|
|
|
49
50
|
---
|
|
50
51
|
|
|
@@ -123,6 +124,44 @@ bun run src/index.ts
|
|
|
123
124
|
|
|
124
125
|
---
|
|
125
126
|
|
|
127
|
+
## React Native / Expo
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm add @elliots/metro-transformer-typical
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Update your `metro.config.js`:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
// metro.config.js
|
|
137
|
+
const { getDefaultConfig } = require("expo/metro-config");
|
|
138
|
+
const { withTypical } = require("@elliots/metro-transformer-typical");
|
|
139
|
+
|
|
140
|
+
module.exports = withTypical(getDefaultConfig(__dirname));
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
For vanilla React Native (without Expo):
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
// metro.config.js
|
|
147
|
+
const { getDefaultConfig } = require("@react-native/metro-config");
|
|
148
|
+
const { withTypical } = require("@elliots/metro-transformer-typical");
|
|
149
|
+
|
|
150
|
+
module.exports = withTypical(getDefaultConfig(__dirname));
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
With options:
|
|
154
|
+
|
|
155
|
+
```js
|
|
156
|
+
module.exports = withTypical(getDefaultConfig(__dirname), {
|
|
157
|
+
typical: {
|
|
158
|
+
validateCasts: true,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
126
165
|
## Bundlers (Vite, Webpack, Rollup, esbuild)
|
|
127
166
|
|
|
128
167
|
```bash
|
|
@@ -352,6 +391,10 @@ The generated validation code is optimised for runtime performance:
|
|
|
352
391
|
|
|
353
392
|
- **Reusable validators** - When the same type is validated multiple times, Typical hoists the validation logic to a reusable function at module scope. Nested types that appear in multiple places (e.g., `Address` used in both `User` and `Company`) are also extracted and reused.
|
|
354
393
|
- **Smart redundancy elimination** - Skips validation when returning values that are already known to be valid: validated parameters, properties of validated objects, variables assigned from casts or `JSON.parse`, and aliased variables
|
|
394
|
+
- **Cross-file call graph analysis** - Analyses the entire project to eliminate redundant validation across files:
|
|
395
|
+
- **Trusted return values** - If a function validates its return type, callers don't re-validate the result
|
|
396
|
+
- **Internal function parameters** - Non-exported functions only called with pre-validated arguments skip parameter validation
|
|
397
|
+
- **Chained function calls** - When `step2(step1(user))` is called, validation flows through the chain
|
|
355
398
|
- **Type-aware dirty tracking** - Tracks when validated values might become invalid. Primitives stay valid after being passed to functions (they're copied), but objects are re-validated if passed to unknown functions. Pure functions (listed in the config) like `console.log` don't invalidate objects.
|
|
356
399
|
- **Union early bail-out** - Union type checks use if-else chains so the first matching type succeeds immediately
|
|
357
400
|
- **Skip comments** - Add `// @typical-ignore` before a function to skip all validation for it
|
|
@@ -478,3 +521,22 @@ Runtime validation performance comparing Typical vs Zod vs no validation:
|
|
|
478
521
|
|
|
479
522
|
- **vs Nothing**: Speed relative to no validation or filtering (1.0x = same speed)
|
|
480
523
|
- **vs Zod**: Speed relative to Zod (1.0x = same speed)
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## Changelog
|
|
528
|
+
|
|
529
|
+
<!-- CHANGELOG_START -->
|
|
530
|
+
|
|
531
|
+
### v0.3.1 (2026-02-23)
|
|
532
|
+
|
|
533
|
+
Add metro transformer (React Native/Expo)
|
|
534
|
+
|
|
535
|
+
### v0.3.0 (2026-01-14)
|
|
536
|
+
|
|
537
|
+
- Build call graph across whole project to avoid validating already-validated data
|
|
538
|
+
- Source map vis in the playround
|
|
539
|
+
- Add 'never' support, the property must not exist
|
|
540
|
+
- Fix: Node 24
|
|
541
|
+
|
|
542
|
+
<!-- CHANGELOG_END -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elliots/typical",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Runtime safe TypeScript transformer using typia",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"runtime",
|
|
@@ -40,19 +40,27 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"commander": "14.0.2",
|
|
43
|
-
"@elliots/typical-compiler": "0.
|
|
43
|
+
"@elliots/typical-compiler": "0.3.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "22",
|
|
47
47
|
"c8": "10.1.3",
|
|
48
|
+
"nano-staged": "^0.9.0",
|
|
48
49
|
"oxfmt": "^0.21.0",
|
|
49
50
|
"oxlint": "1.36.0",
|
|
50
51
|
"oxlint-tsgolint": "0.10.1",
|
|
52
|
+
"simple-git-hooks": "^2.13.1",
|
|
51
53
|
"typescript": "5.9.3"
|
|
52
54
|
},
|
|
53
55
|
"peerDependencies": {
|
|
54
56
|
"typescript": "^5.0.0"
|
|
55
57
|
},
|
|
58
|
+
"simple-git-hooks": {
|
|
59
|
+
"pre-commit": "pnpm nano-staged"
|
|
60
|
+
},
|
|
61
|
+
"nano-staged": {
|
|
62
|
+
"*.{js,ts,tsx,jsx,json,md,html,css}": "oxfmt"
|
|
63
|
+
},
|
|
56
64
|
"engines": {
|
|
57
65
|
"pnpm": ">=10"
|
|
58
66
|
},
|
|
@@ -67,7 +75,7 @@
|
|
|
67
75
|
"build:ts": "pnpm --filter './packages/*' run build && tsc",
|
|
68
76
|
"build:website": "pnpm --filter typical-website run build",
|
|
69
77
|
"dev": "tsc --watch",
|
|
70
|
-
"test": "rm -f test/test.temp.ts && tsc && node --import ./dist/src/esm-loader-register.js --test dist/test/*.test.js",
|
|
78
|
+
"test": "rm -f test/test.temp.ts && rm -rf test/project-fixtures && tsc && node --import ./dist/src/esm-loader-register.js --test dist/test/*.test.js",
|
|
71
79
|
"test:coverage": "rm -f test/test.temp.ts && tsc && node --import ./dist/src/esm-loader-register.js --test --experimental-test-coverage dist/test/*.test.js",
|
|
72
80
|
"test:coverage:html": "rm -f test/test.temp.ts && tsc && c8 --reporter=html --reporter=text --include='dist/src/**' node --import ./dist/src/esm-loader-register.js --test dist/test/*.test.js",
|
|
73
81
|
"bench": "pnpm run build && cd bench && pnpm install && npm run bench",
|
|
@@ -78,6 +86,7 @@
|
|
|
78
86
|
"sample:ttsc": "cd samples/ttsc && pnpm install && npm run build && npm run start",
|
|
79
87
|
"sample:vite-react": "cd samples/vite-react && pnpm install && pnpm run test",
|
|
80
88
|
"sample:bun": "cd samples/bun && pnpm install && bun run start",
|
|
89
|
+
"sample:react-native": "cd samples/react-native && pnpm install && npm run web",
|
|
81
90
|
"samples": "npm run sample:esm && npm run sample:ttsx && npm run sample:vite-react && npm run sample:bun",
|
|
82
91
|
"publish:all": "npm run lint && npm run format:check && node scripts/publish.js"
|
|
83
92
|
}
|