Strongly typed string functions
When you are working with literal strings, the string manipulation functions only work at the runtime level and the types don't follow those transformations. You end up losing type information and possibly having to cast the result.
const str = 'hello-world'
const result = str.replace('-', ' ') // you should use: as 'hello world'
// ^? stringThis library aims to solve this problem by providing a set of common functions that work with literal strings at both type and runtime level.
import { replace } from 'string-ts'
const str = 'hello-world'
const result = replace(str, '-', ' ')
// ^ 'hello world'TypeScript yields the best static analysis when types are highly specific.
Literals are more specific than type string.
This library preserves literals (and unions of literals) after transformations, unlike most existing utility libraries (and built-in string methods.)
I still don't get the purpose of this library
In the below example, I want to get a strongly-typed, camel-case version of process.env.
One flow results in a loose type, and the other results in a more precise type.
This example should illustrate the highly-specific and flexible nature of string-ts.
…npm install string-tsstring-ts has been designed with tree shaking in mind.
We have tested it with build tools like Webpack, Vite, Rollup, etc.
string-ts currently only works on TypeScript v5+.
See also: Known limitations.
Extracting functions from string-ts is the recommended usage, but if you'd like to apply strongly-typed versions of native string methods project-wide, you can do so with a single import.
Inspired by ts-reset, this import overrides the native String.prototype type declarations, giving you strong typing for supported methods like charAt, startsWith, endsWith, replace, split, and more.
import 'string-ts/native'
const str = 'hello-world' as const
str.replace('-', '_')
// ^? 'hello_world'
str.charAt(6)
// ^? 'w'
str.startsWith('hello')
// ^? true
str.split('-')
// ^? ['hello', 'world']This has minimal impact on type-checker performance. In our tests, TSC went from 17.21s to 17.41s.
Note: Only methods already supported by the library are typed. The length property cannot be strongly-typed as it's a read-only property, not a method.
Capitalizes the first letter of a string. This is a runtime counterpart of Capitalize from src/types.d.ts.
import { capitalize } from 'string-ts'
const str = 'hello world'
const result = capitalize(str)
// ^ 'Hello world'Uncapitalizes the first letter of a string. This is a runtime counterpart of Uncapitalize from src/types.d.ts.
import { uncapitalize } from 'string-ts'
const str = 'Hello world'
const result = uncapitalize(str)
// ^ 'hello world'This function is a strongly-typed counterpart of String.prototype.charAt.
import { charAt } from 'string-ts'
const str = 'hello world'
const result = charAt(str, 6)
// ^ 'w'This function is a strongly-typed counterpart of String.prototype.concat.
import { concat } from 'string-ts'
const result = concat('a', 'bc', 'def')
// ^ 'abcdef'This function is a strongly-typed counterpart of String.prototype.endsWith.
import { endsWith } from 'string-ts'
const result = endsWith('abc', 'c')
// ^ trueThis function is a strongly-typed counterpart of String.prototype.includes.
import { includes } from 'string-ts'
const result = includes('abcde', 'bcd')
// ^ trueThis function is a strongly-typed counterpart of Array.prototype.join.
import { join } from 'string-ts'
const str = ['hello', 'world']
const result = join(str, ' ')
// ^ 'hello world'This function is a strongly-typed counterpart of String.prototype.length.
import { length } from 'string-ts'
const str = 'hello'
const result = length(str)
// ^ 5This function is a strongly-typed counterpart of String.prototype.padEnd.
import { padEnd } from 'string-ts'
const str = 'hello'
const result = padEnd(str, 10, '=')
// ^ 'hello====='This function is a strongly-typed counterpart of String.prototype.padStart.
import { padStart } from 'string-ts'
const str = 'hello'
const result = padStart(str, 10, '=')
// ^ '=====hello'This function is a strongly-typed counterpart of String.prototype.repeat.
Note: for counts above 45 the return type falls back to string to avoid TypeScript's type-instantiation depth limit. See Known limitations.
import { repeat } from 'string-ts'
const str = 'abc'
const result = repeat(str, 3)
// ^ 'abcabcabc'This function is a strongly-typed counterpart of String.prototype.replace.
Warning: this is a partial implementation, as we don't fully support Regex. Using a RegExp lookup will result in a loose typing.
import { replace } from 'string-ts'
const str = 'hello-world-'
const result = replace(str, '-', ' ')
// ^ 'hello world-'
const looselyTypedResult = replace(str, /-/, ' ')
// ^ stringThis function is a strongly-typed counterpart of String.prototype.replaceAll.
It also has a polyfill for runtimes older than ES2021.
Warning: this is a partial implementation, as we don't fully support Regex. Using a RegExp lookup will result in a loose typing.
import { replaceAll } from 'string-ts'
const str = 'hello-world-'
const result = replaceAll(str, '-', ' ')
// ^ 'hello world '
const looselyTypedResult = replaceAll(str, /-/g, ' ')
// ^ stringThis function is a strongly-typed counterpart of String.prototype.slice.
import { slice } from 'string-ts'
const str = 'hello-world'
const result = slice(str, 6)
// ^ 'world'
const result2 = slice(str, 1, 5)
// ^ 'ello'
const result3 = slice(str, -5)
// ^ 'world'This function is a strongly-typed counterpart of String.prototype.split.
import { split } from 'string-ts'
const str = 'hello-world'
const result = split(str, '-')
// ^ ['hello', 'world']This function is a strongly-typed counterpart of String.prototype.startsWith.
import { startsWith } from 'string-ts'
const result = startsWith('abc', 'a')
// ^ trueThis function is a strongly-typed counterpart of String.prototype.toLowerCase.
import { toLowerCase } from 'string-ts'
const str = 'HELLO WORLD'
const result = toLowerCase(str)
// ^ 'hello world'This function is a strongly-typed counterpart of String.prototype.toUpperCase.
import { toUpperCase } from 'string-ts'
const str = 'hello world'
const result = toUpperCase(str)
// ^ 'HELLO WORLD'This function is a strongly-typed counterpart of String.prototype.trim.
import { trim } from 'string-ts'
const str = ' hello world '
const result = trim(str)
// ^ 'hello world'This function is a strongly-typed counterpart of String.prototype.trimEnd.
import { trimEnd } from 'string-ts'
const str = ' hello world '
const result = trimEnd(str)
// ^ ' hello world'This function is a strongly-typed counterpart of String.prototype.trimStart.
import { trimStart } from 'string-ts'
const str = ' hello world '
const result = trimStart(str)
// ^ 'hello world 'This function converts a string to lower case at both runtime and type levels.
NOTE: this function will split by words and join them with " ", unlike toLowerCase.
import { lowerCase } from 'string-ts'
const str = 'HELLO-WORLD'
const result = lowerCase(str)
// ^ 'hello world'This function converts a string to camelCase at both runtime and type levels.
import { camelCase } from 'string-ts'
const str = 'hello-world'
const result = camelCase(str)
// ^ 'helloWorld'This function converts a string to CONSTANT_CASE at both runtime and type levels.
import { constantCase } from 'string-ts'
const str = 'helloWorld'
const result = constantCase(str)
// ^ 'HELLO_WORLD'This function converts a string to a new case with a custom delimiter at both runtime and type levels.
import { delimiterCase } from 'string-ts'
const str = 'helloWorld'
const result = delimiterCase(str, '.')
// ^ 'hello.World'This function converts a string to kebab-case at both runtime and type levels.
import { kebabCase } from 'string-ts'
const str = 'helloWorld'
const result = kebabCase(str)
// ^ 'hello-world'This function converts a string to PascalCase at both runtime and type levels.
import { pascalCase } from 'string-ts'
const str = 'hello-world'
const result = pascalCase(str)
// ^ 'HelloWorld'This function converts a string to snake_case at both runtime and type levels.
import { snakeCase } from 'string-ts'No open issues yet, or sync has not completed.