如何使用不同的键名称干燥两个相似的打字稿界面

Yar*_*ash 2 typescript

我有两种不同格式的相同界面,一种是 JSON 格式,其中键由低破折号分隔,另一种是 javascript 驼峰格式:

JSON 格式:

interface MyJsonInterface {
  key_one: string;
  key_two: number;
}

interface MyInterface {
  keyOne: string;
  keyTwo: number;
}
Run Code Online (Sandbox Code Playgroud)

我想防止重复,但不知道正确的方法。我检查了这个问题,但答案并不令人满意,因为我不希望两个接口都使用相同的按键。

有什么不同的方法吗?

cap*_*ian 6

让我们把这个任务分成更小的子任务。首先,您需要编写一个将转换snake_casecamelCase. 让我们重点关注一下。

看看这个:

type Separator = '_'
type Convert<Str extends string, Acc extends string = ''> =
  // Check if Str mathes the pattern string_string
  (Str extends `${infer Head}${Separator}${infer Tail}`
    // If yes, check whether it is a first call or not, because we don't want to capitalize for part of the string
    ? (Acc extends ''
      // This is a first call, because Acc is empty, hence first part should not be capitalized
      ? Convert<Tail, `${Acc}${Head}`>
      // This is not first call, hence Head should be capitalized
      : Convert<Tail, `${Acc}${Capitalize<Head>}`>)
    // This is the last call, because Str does not match the pattern
    : `${Acc}${Capitalize<Str>}`)

Run Code Online (Sandbox Code Playgroud)

现在,我们可以迭代该接口并将每个键替换为转换后的键:

type Builder<T> = {
  [Prop in keyof T as Convert<Prop & string>]: T[Prop]
}

// {
//     oneTwoThreeFourthFiveSixSevenEightNineTen: "hello";
// }
type Result = Builder<{
  one_two_three_fourth_five_six_seven_eight_nine_ten: 'hello'
}>
Run Code Online (Sandbox Code Playgroud)

带有完整代码的Playground

反之亦然:

type Separator = '_'

type IsChar<Char extends string> = Uppercase<Char> extends Lowercase<Char> ? false : true;

type IsCapitalized<Char extends string> =
  IsChar<Char> extends true
  ? Uppercase<Char> extends Char
  ? true
  : false
  : false

type Replace<Char extends string> =
  IsCapitalized<Char> extends true
  ? `${Separator}${Lowercase<Char>}`
  : Char

type Result2 = Replace<'A'>

type CamelToSnake<
  Str extends string,
  Acc extends string = ''
  > =
  Str extends `${infer Char}${infer Rest}` ? CamelToSnake<Rest, `${Acc}${Replace<Char>}`> : Acc

// type Result = "foo_bar_baz"
type Result = CamelToSnake<'fooBarBaz'>
Run Code Online (Sandbox Code Playgroud)

操场