때때로 당신은 문자열 리터럴 타입이 정해진 타입인지 결정하고 싶을 수 있다. 예를 들어 당신이 클래스 ID로 식별되는 타입이 고정된 문자열 리터럴 타입인지 확인하고 싶을 때다.
type Action<ID extends string> = { readonly id: ID };
이것은 고정되어져야 하기 때문에, 다음 타입들은 false로 결정되어야 한다.
Sometimes you may want to determine whether a string literal is a definite type. For example, when you want to check whether the type specified as a class identifier is a fixed string literal type.
type Action<ID extends string> = { readonly id: ID };
Since it must be fixed, the following types must be determined as false.
type IsNonFixedStringLiteralType<S extends string>=
string extends S?true:
`${number}` extends `${S}`?true:
`${bigint}` extends `${S}`?true:
false
type IsUnion<T,U=T>=T extends U?
[Exclude<U,T>] extends [never] ?false:true
:never
type IsFixedStringLiteralType<S extends string> =
S extends ''?true:
[S] extends [never]?false:
IsUnion<S> extends true?false:
S extends `${infer Head}${infer Rest}`?
IsNonFixedStringLiteralType<Head> extends true?false
:IsFixedStringLiteralType<Rest>
:false
구현체는 해당 문자열이 빈 문자열 ''까지 도달할 수 있는지 여부로 고정된 리터럴 타입인지 확인한다.
우선 never나 유니온인 경우는 false를 반환한다.(이때 boolean은 false와 true의 유니온 타입으로 처리 된다)
그리고 문자열의 첫 번째 문자를 확인하여 그 문자의 타입이 정확히 string/number/bigint이거나, 이 타입들보다 큰 타입인 경우(ex:string&{}) false를 반환한다.
첫 번째 문자가 위의 조건에 해당되지 않는 경우 뒤의 문자열을 다시 재귀적으로 판단하여 ''까지 갈 수 있는지 확인한다.