Reputation: 3588
I know in TypeScript we can enforce specific strings like so:
const myStrings = ['foo', 'bar', 'baz'] as const;
type MyStringTypes = typeof myStrings[number];
However, what I would need is to enforce only the first characters of my final strings.
For instance, I would like to create a type (MyPrefixTypes
) with something like 'prefix1'
, 'prefix2'
, ..., 'prefixN'
, followed by any other character.
Using this, I would be able to check if the string is correct or not.
Example:
const foo: MyPrefixTypes = 'prefix1blablabla'; // OK
const bar: MyPrefixTypes = 'incorrectprefixblablabla'; // NOT OK
Upvotes: 46
Views: 15829
Reputation: 14128
As of TypeScript 4.1, you can use a template literal type for this.
type StartsWithPrefix = `prefix${string}`;
This works for type unions as well:
// `abc${string}` | `def${string}`
type UnionExample = `${'abc' | 'def'}${string}`;
// For your example:
type MyPrefixTypes = `${MyStringTypes}${string}`;
const ok: UnionExample = 'abc123';
const alsoOk: UnionExample = 'def123';
const notOk: UnionExample = 'abdxyz';
// Note that a string consisting of just the prefix is allowed
// (because '' is assignable to string so
// `${SomePrefix}${''}` == SomePrefix is valid)
const ok1: MyPrefixTypes = 'foo'
const ok2: MyPrefixTypes = 'barxyz'
const ok3: MyPrefixTypes = 'bazabc'
const notOk1: MyPrefixTypes = 'quxfoo'
You can even define a helper type:
type WithPrefix<T extends string> = `${T}${string}`;
type StartsWithPrefix = WithPrefix<'prefix'>;
type UnionExample = WithPrefix<'abc' | 'def'>;
type MyPrefixTypes = WithPrefix<MyStringTypes>;
Related:
Upvotes: 84