Open egeozcan opened 3 years ago
@gcanti wouldn't a function like t.templateLiteral(``)
solve this problem? I'm answering to your tag addition.
An example: https://github.com/colinhacks/zod/issues/419
Template Literals could be modelled as a refinement of the string codec. Unfortunately, there seems to be no way to let TypeScript knows about the relationship between a template string or regex at runtime and the template literal type at compile time, so some duplication is inevitable when declaring the codec, but at least the usage would be coherent and correct from there. A proposal:
import * as t from 'io-ts';
export function templateLiteral<L extends string>(regex: RegExp | string, name?: string) {
const regex_ = typeof regex === 'string' ? new RegExp(regex) : regex;
const predicate = (s: string): s is L => regex_.test(s);
return new t.RefinementType(
name ?? `TemplateLiteral<${regex_.source}>`,
(u): u is L => t.string.is(u) && predicate(u),
(i, c) => {
const e = t.string.validate(i, c);
if (isLeft(e)) {
return e;
}
const a = e.right;
return predicate(a) ? t.success(a) : t.failure(a, c);
},
t.string.encode,
t.string,
predicate,
);
}
// Usage
const hexString = templateLiteral<`0x{string}`>(/^0x.*/);
declare const str: unknown;
if (hexString.is(str)) {
// type of str: `0x{string}`
}
Thanks for the nice example!
Spotted a typo, missing $
: it should probably be
const hexString = templateLiteral<`0x${string}`>(/^0x.*/);
^
🚀 Feature request
TypeScript introduced Template Literal Types in version 4.1: https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#template-literal-types
https://www.typescriptlang.org/play?ts=4.1.0-pr-40336-88#code/JYOwLgpgTgZghgYwgAgILIN4ChnIMoD2AthACJyQBcy5kA3DvsRAJLjUByArkQEbQMAvlixgAngAcUAMWAAbSFAAqAHiUAaZEoAKUAhOQQAHpBAATAM7IA1hDEEYWgHzIAvJkYBtW2OShkAAYAJBgA5ACyoKHIAD7IEXBG0XGhoYIhFmBQoADmyABkWrr6grIK0AEAutRKnjp6EpVCIi0i4lLI0m6d8oqqqJqhhCS0EKFODK1TIkA
Current Behavior
There's no way (AFAIK) to use template literal types with io-ts.
Desired Behavior
I can replicate Template Literal Types with io-ts.
Suggested Solution
A function like
t.templateLiteral(``)
that replicates the behavior.Who does this impact? Who is this for?
People generating types from types.
Describe alternatives you've considered
I'm currently using a script to generate these types. They have to be known at compile time anyway.
Your environment