# 651-字符长度2

# 题目描述

Implement a type LengthOfString<S> that calculates the length of the template string (as in 298 - Length of String):

type T0 = LengthOfString<'foo'>; // 3

The type must support strings several hundred characters long (the usual recursive calculation of the string length is limited by the depth of recursive function calls in TS, that is, it supports strings up to about 45 characters long).

# 分析

可以先看下 298 - Length of String 的解法,其实思路有两种:

思路一:遍历字符,生成元组,元组的长度就是结果

type StringToUnion<S extends string> = S extends `${string}${infer R}`
  ? [1, ...StringToUnion<R>]
  : [];

type LengthOfString<S extends string> = StringToUnion<S>['length'];

思路二:遍历字符,并引入辅助计数元组 Arr,当遍历结束,辅助元组的长度就是结果

type LengthOfString<
  S extends string,
  Arr extends any[] = [],
> = S extends `${string}${infer R}`
  ? LengthOfString<R, [...Arr, 1]>
  : Arr['length'];

带入用例中,会发现,对于长字符(一般超过 45 个),思路一的解法就失效了,会报 Type instantiation is excessively deep and possibly infinite. 错误。

而对于思路二的解法,字符长度 1000 以内 (不包括 1000) 都不会报错。超过 1000, 也会报 Type instantiation is excessively deep and possibly infinite. 错误。

具体原因可以查看: 冷门-递归深度。本题目通过思路二就可以覆盖所有用例

# 题解

type LengthOfString<
  S extends string,
  Arr extends any[] = [],
> = S extends `${string}${infer R}`
  ? LengthOfString<R, [...Arr, 1]>
  : Arr['length'];

# 知识点

  1. 递归深度限制:45
  2. 递归过深优化: 可以到 1000
  3. 字符遍历
  4. 元组计数
Last Updated: 2023/5/16 06:00:28