type-challenges icon indicating copy to clipboard operation
type-challenges copied to clipboard

110 - Capitalize

Open pandanoir opened this issue 5 years ago • 6 comments

// your answers
type Capitalize<S extends string> = S extends `${infer x}${infer tail}` ? `${Uppercase<x>}${tail}` : S;

pandanoir avatar Jan 26 '21 12:01 pandanoir

How does typescript determine which of x and tail should take up the rest characters? For example, if S is 'abc', why are x='a' and tail='bc', not x='ab' and tail='c? Is there any docs I can refer to?

kc0506 avatar Oct 01 '23 04:10 kc0506

I'm interested too about question @kc0506

igor-morev avatar Nov 02 '23 10:11 igor-morev

I was looking for a specification document, but I couldn't find a sentence that was explicitly written.

I can only say, "It's such a specification because it works like this". But it should be unlikely that this specification will be changed, so that will be the answer once.

pandanoir avatar Nov 02 '23 10:11 pandanoir

How does typescript determine which of x and tail should take up the rest characters? For example, if S is 'abc', why are x='a' and tail='bc', not x='ab' and tail='c? Is there any docs I can refer to?

Here is my own understanding (English is machine translated, Mainly looking at the code please)

下面是我自己的理解(英文是机翻的,主要看代码)

If a string is only inferred using infer without any other information, the previous infer will only infer one character at a time, and the last infer will infer all the remaining characters, such as:

如果字符串仅使用 infer 进行推导而不参杂其他信息,那前面的 infer 每次只会推导出一个字符,最后一个 infer 会推导出剩下所有的字符,如:

type Split<S> = S extends `${infer l}${infer r}` ? `${l} ${r}` : never
// Split<'123-4567890'> -> l = '1', r = '23-4567890' -> result = '1 23-457890'

If certain deduction conditions (string value type, It can be regarded as a constant) are added in the string's middle, the string will be divided according to the deduction conditions:

如果字符串中间添加某些推导条件(字符串值类型,可以看成常量),那则会按照推导条件进行字符串的分割:

type Split<S> = S extends `${infer l}-${infer r}` ? `${l} ${r}` : never
// Split<'123-4567890'> -> l = '123', r = '4567890' -> result = '123 4567890'

GodAraden avatar Nov 04 '23 12:11 GodAraden

@kc0506, @Morev1993 I guess it's like:

${infer A}${T}${infer B} - first occurrence of type T and infer everything before it as A and after it as B

If there is no T, A will be the first literal (character).

orl0 avatar Nov 07 '23 09:11 orl0

How does typescript determine which of x and tail should take up the rest characters? For example, if S is 'abc', why are x='a' and tail='bc', not x='ab' and tail='c? Is there any docs I can refer to?

Upon testing, I reckon this is how it works:

TypeScript Regex
${infer A} /(.*)/
${infer A}${infer B} /(.+?)(.*)/
${infer A}${infer B}${infer C} /(.+?)(.+?)(.*)/

wheatup avatar May 27 '24 02:05 wheatup