Il s'agit d'une question continue avec cette question : existe-t-il un moyen de différencier une chaîne de caractères et un modèle de chaîne de caractères ?
type Data = {
arrayObject: {
firstName: string;
lastName: string;
}[];
};
type ArrayElementType<A> = A extends readonly (infer T)[] ? T : never
type TupleOf<A extends number, R extends number[] = []> =
R['length'] extends A ? R : TupleOf<A, [...R, R['length']]>;
type Integers = TupleOf<1>;
type Indexes = Integers[number];
type PathFinder<T, Key extends keyof T = keyof T> = Key extends string
? T[Key] extends (string | boolean | number | symbol)[]
? `${Key}.${Indexes}`
: T[Key] extends object[]
? `${Key}.${Indexes}.${PathFinder<ArrayElementType<T[Key]>>}`
: T[Key] extends Record<string, any>
? `${Key}.${PathFinder<T[Key]>}`
: Key
: never;
function register<Data>(name: PathFinder<Data>) {
console.log(name)
}
const index = '0'
register(`arrayObject.${index}.lastName` as const); // works for TS 4.1
register(`arrayObject.${index}.lastName`); // works for TS 4.2
const i:number = '0'
register(`arrayObject.${index}.lastName` as const); fail
register(`arrayObject.${index}.lastName`); // fail
Cependant, lorsque l'index est dynamique et que le type sera number
par exemple, il peut entraîner une for
lop
ce qui casse à nouveau le type. Existe-t-il un moyen d'inclure le number
o string
dans le type de littéral de chaîne du modèle ?