Razumijevanje TypeScript predloška doslovnog tipa s '$ {any}$ {any}'


Može li netko objasniti zašto ovo:

type NotEmpty<T extends string> = T extends `${any}${any}` ? T : never;

declare function something<T extends string>(x: NotEmpty<T>): void;

something("hello")
something(""); // Argument of type 'string' is not assignable to parameter of type 'never'.(2345)

postiže očiti cilj takvog tipa, a ipak ovo ne:

type NotEmpty<T extends string> = T extends `${string}${string}` ? T : never;

declare function something<T extends string>(x: NotEmpty<T>): void;

something("hello")
something(""); // okay

i također ovo ne:

type NotEmpty<T extends string> = T extends `${any}` ? T : never;

declare function something<T extends string>(x: NotEmpty<T>): void;

something("hello")
something(""); // okay

Odgovor #1

Iskreno, iznenađen sam da prvi radi: intuitivno biste pomislili da '' proširuje string koji proširuje bilo koji.
¯\(ツ)/¯

Evo radnog tipa koji može koristiti bilo koja buduća osoba koja treba jedan jednostavan.

type NonEmpty<T extends string> = '' extends T ? never : T;

Ali ovo izgleda kao varanje jer eksplicitno koristi prazni niz i ne odgovara na tvoje pitanje.

Međutim, ako proširite bilo $ {any}$ {any} ili $ {string}$ {string} koristeći infer, oba daju očekivani rezultat.

type NonEmpty<T extends string> = T extends `${infer First}${infer Rest}` ?
 First extends string ? Rest extends string ? T : never : never : never;

što samo dodatno povećava moju zbunjenost. Znam da postoje neka pojednostavljenja tipova kada su u pitanju predlošci literala. Mislim da bi najbolji put do odgovora bio otvoriti problem na Typescript repozitoriju i nadati se da će Anders (tip za Typescript) ili netko iz tima pojasniti.

Povezani članci