阿里云主机折上折
  • 微信号
Current Site:Index > String manipulation types translate this sentence into English, output only plain text, do not output anything else.

String manipulation types translate this sentence into English, output only plain text, do not output anything else.

Author:Chuan Chen 阅读数:55684人阅读 分类: TypeScript

String Manipulation Types

TypeScript provides several built-in utility types for handling string types. These types enable operations such as concatenation, replacement, case conversion, and more, significantly enhancing the expressiveness of the type system.

Template Literal Types

Template literal types allow combining string types through interpolation:

type World = "world";
type Greeting = `hello ${World}`;  // "hello world"

type Vertical = "top" | "middle" | "bottom";
type Horizontal = "left" | "center" | "right";
type Position = `${Vertical}-${Horizontal}`;
// "top-left" | "top-center" | "top-right" | 
// "middle-left" | "middle-center" | "middle-right" | 
// "bottom-left" | "bottom-center" | "bottom-right"

Case Conversion

Uppercase, Lowercase, Capitalize, and Uncapitalize are four built-in string transformation types:

type UppercaseStr = Uppercase<"typescript">;  // "TYPESCRIPT"
type LowercaseStr = Lowercase<"TYPESCRIPT">;  // "typescript"
type Capitalized = Capitalize<"typescript">;  // "Typescript"
type Uncapitalized = Uncapitalize<"Typescript">;  // "typescript"

String Splitting and Joining

String splitting can be achieved through type inference:

type Split<S extends string, D extends string> =
    S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [S];

type PathParts = Split<"src/components/Button.tsx", "/">;
// ["src", "components", "Button.tsx"]

Joining string arrays:

type Join<T extends string[], D extends string> =
    T extends [] ? "" :
    T extends [infer F] ? F :
    T extends [infer F, ...infer R] ? `${F & string}${D}${Join<R, D>}` : string;

type Path = Join<["src", "components", "Button.tsx"], "/">;
// "src/components/Button.tsx"

String Replacement

Implementing string replacement:

type Replace<
    S extends string,
    From extends string,
    To extends string
> = From extends ""
    ? S
    : S extends `${infer Prefix}${From}${infer Suffix}`
    ? `${Prefix}${To}${Suffix}`
    : S;

type Replaced = Replace<"TypeScript is awesome", "awesome", "great">;
// "TypeScript is great"

String Pattern Matching

Using conditional types for pattern matching:

type ExtractQueryParam<S extends string> =
    S extends `${string}?${infer Query}` ? Query : never;

type QueryString = ExtractQueryParam<"/user?id=123&name=foo">;
// "id=123&name=foo"

String Length Calculation

Recursively calculating string length:

type StringLength<S extends string> = 
    S extends `${infer First}${infer Rest}` 
    ? StringLength<Rest> extends infer Length 
      ? [First, ...(Length extends any[] ? Length : [])]
      : never
    : [];

type Length = StringLength<"hello">["length"];  // 5

Prefix/Suffix Checking

Checking if a string starts or ends with a specific pattern:

type StartsWith<S extends string, Prefix extends string> = 
    S extends `${Prefix}${string}` ? true : false;

type EndsWith<S extends string, Suffix extends string> = 
    S extends `${string}${Suffix}` ? true : false;

type HasPrefix = StartsWith<"TypeScript", "Type">;  // true
type HasSuffix = EndsWith<"TypeScript", "Script">;  // true

String Slicing

Implementing JavaScript-like slice operations:

type Slice<
    S extends string,
    Start extends number,
    End extends number,
    Result extends string = "",
    Count extends any[] = []
> = Count["length"] extends End
    ? Result
    : Count["length"] extends Start
    ? Slice<S, Start, End, `${Result}${S[Start]}`, [...Count, any]>
    : Count["length"] extends number
    ? Slice<S, Start, End, Result, [...Count, any]>
    : never;

type Sliced = Slice<"TypeScript", 4, 10>;  // "Script"

String Reversal

Recursively reversing a string:

type ReverseString<S extends string> =
    S extends `${infer First}${infer Rest}`
    ? `${ReverseString<Rest>}${First}`
    : S;

type Reversed = ReverseString<"TypeScript">;  // "tpircSepyT"

Whitespace Trimming

Handling whitespace at both ends of a string:

type TrimLeft<S extends string> =
    S extends ` ${infer Rest}` ? TrimLeft<Rest> : S;

type TrimRight<S extends string> =
    S extends `${infer Rest} ` ? TrimRight<Rest> : S;

type Trim<S extends string> = TrimLeft<TrimRight<S>>;

type Trimmed = Trim<"  TypeScript  ">;  // "TypeScript"

Substring Inclusion Check

Checking if a string contains a substring:

type Includes<
    S extends string,
    Sub extends string
> = S extends `${string}${Sub}${string}` ? true : false;

type Contains = Includes<"TypeScript", "Script">;  // true

String Repetition

Implementing string repetition:

type Repeat<
    S extends string,
    N extends number,
    Result extends string = "",
    Count extends any[] = []
> = Count["length"] extends N
    ? Result
    : Repeat<S, N, `${Result}${S}`, [...Count, any]>;

type Repeated = Repeat<"A", 5>;  // "AAAAA"

String Padding

Implementing padStart and padEnd functionality:

type PadStart<
    S extends string,
    N extends number,
    Fill extends string = " ",
    Current extends string = S
> = Current extends infer Str 
    ? Str extends string
      ? StringLength<Str> extends N
        ? Str
        : PadStart<S, N, Fill, `${Fill}${Str}`>
      : never
      : never;

type Padded = PadStart<"42", 5, "0">;  // "00042"

Character Extraction

Extracting a character at a specific position:

type CharAt<
    S extends string,
    N extends number,
    Count extends any[] = []
> = Count["length"] extends N
    ? S extends `${infer Char}${string}`
      ? Char
      : never
    : S extends `${string}${infer Rest}`
    ? CharAt<Rest, N, [...Count, any]>
    : never;

type Char = CharAt<"TypeScript", 4>;  // "S"

String Encoding Conversion

Simulating string encoding conversion:

type EncodeURIComponent<S extends string> =
    S extends `${infer Head}${infer Tail}`
    ? Head extends " "
      ? `%20${EncodeURIComponent<Tail>}`
      : Head extends "!"
      ? `%21${EncodeURIComponent<Tail>}`
      // Other character handling...
      : `${Head}${EncodeURIComponent<Tail>}`
    : S;

type Encoded = EncodeURIComponent<"hello world!">;  // "hello%20world%21"

String Comparison

Implementing lexicographical string comparison:

type CompareStrings<
    A extends string,
    B extends string
> = A extends B
    ? 0
    : A extends `${infer AChar}${infer ARest}`
    ? B extends `${infer BChar}${infer BRest}`
      ? AChar extends BChar
        ? CompareStrings<ARest, BRest>
        : AChar extends string
        ? BChar extends string
          ? AChar extends Exclude<string, BChar>
            ? 1
            : -1
          : never
        : never
      : 1
    : B extends `${string}${string}`
    ? -1
    : 0;

type Comparison = CompareStrings<"apple", "banana">;  // -1 (apple < banana)

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.