Skip to content

Commit

Permalink
Replace: Add support for generating longer strings (#1060)
Browse files Browse the repository at this point in the history
  • Loading branch information
som-sm authored Feb 27, 2025
1 parent a463c30 commit 3c03a0d
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
12 changes: 10 additions & 2 deletions source/replace.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,16 @@ export type Replace<
Search extends string,
Replacement extends string,
Options extends ReplaceOptions = {},
> = _Replace<Input, Search, Replacement, Options>;

type _Replace<
Input extends string,
Search extends string,
Replacement extends string,
Options extends ReplaceOptions,
Accumulator extends string = '',
> = Input extends `${infer Head}${Search}${infer Tail}`
? Options['all'] extends true
? `${Head}${Replacement}${Replace<Tail, Search, Replacement, Options>}`
? _Replace<Tail, Search, Replacement, Options, `${Accumulator}${Head}${Replacement}`>
: `${Head}${Replacement}${Tail}`
: Input;
: `${Accumulator}${Input}`;
12 changes: 11 additions & 1 deletion test-d/replace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {expectType} from 'tsd';
import type {Replace} from '../index';
import type {Replace, StringRepeat} from '../index';

declare function replace<
Input extends string,
Expand Down Expand Up @@ -27,3 +27,13 @@ expectType<'10-42-00'>(replaceAll('10:42:00', ':', '-'));
expectType<'userName'>(replaceAll('__userName__', '__', ''));
expectType<'MyCoolTitle'>(replaceAll('My Cool Title', ' ', ''));
expectType<'fobarfobar'>(replaceAll('foobarfoobar', 'ob', 'b'));

// Recursion depth at which a non-tail recursive implementation starts to fail.
type FiftyZeroes = StringRepeat<'0', 50>;
type FiftyOnes = StringRepeat<'1', 50>;
expectType<FiftyOnes>({} as Replace<FiftyZeroes, '0', '1', {all: true}>);

// Maximum allowed recursion depth for a tail recursive implementation.
type NineHundredNinetyNineZeroes = StringRepeat<'0', 999>;
type NineHundredNinetyNineOnes = StringRepeat<'1', 999>;
expectType<NineHundredNinetyNineOnes>({} as Replace<NineHundredNinetyNineZeroes, '0', '1', {all: true}>);
10 changes: 5 additions & 5 deletions test-d/split.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {expectType} from 'tsd';
import type {Split} from '../index';
import type {Split, StringRepeat} from '../index';
import type {BuildTuple} from '../source/internal';

declare function split<
Expand Down Expand Up @@ -31,9 +31,9 @@ expectType<[]>(split('', ''));
expectType<['']>(split('', ' '));

// Recursion depth at which a non-tail recursive implementation starts to fail.
const fiftyZeroes = '00000000000000000000000000000000000000000000000000';
expectType<BuildTuple<50, '0'>>(split(fiftyZeroes, ''));
type FiftyZeroes = StringRepeat<'0', 50>;
expectType<BuildTuple<50, '0'>>({} as Split<FiftyZeroes, ''>);

// Maximum allowed recursion depth for a tail recursive implementation.
const nineHundredNinetyNineZeroes = '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
expectType<BuildTuple<999, '0'>>(split(nineHundredNinetyNineZeroes, ''));
type NineHundredNinetyNineZeroes = StringRepeat<'0', 999>;
expectType<BuildTuple<999, '0'>>({} as Split<NineHundredNinetyNineZeroes, ''>);

0 comments on commit 3c03a0d

Please sign in to comment.