英文:
Is it possible for typescript to continue to infer the exact values of an array marked "as const" after it goes through an operation?
问题
const myArray = ["foo", 3.14, true] as const;
Typescript will infer that this array is:
readonly ["foo", 3.14, true]
So it knows exactly what the array is.
I'm trying to increase my knowledge of typescript, and I'm trying to figure out if it's possible to perform a generic operation on this array as const
and preserve typescript's inference of these values.
For example, is it possible to write a function in typescript called convertNumbersToStrings()
that accepts any readonly array as an argument and outputs another readonly array where, if I pass my as const
array, typescript can infer that the result is: ["foo", "3.14", true]?
英文:
Say I have this array:
const myArray = ["foo", 3.14, true] as const;
Typescript will infer that this array is:
readonly ["foo", 3.14, true]
So it knows exactly what the array is.
I'm trying to increase my knowledge of typescript, and I'm trying to figure out if it's possible to perform a generic operation on this array as const
and preserve typescript's inference of these values.
For example, is it possible to write a function in typescript called convertNumbersToStrings()
that accepts any readonly array as an argument and outputs another readonly array where, if I pass my as const
array, typescript can infer that the result is: ["foo", "3.14", true]
?
答案1
得分: 1
Yes, it is possible (thanks to @Blackhole for correcting my Sunday night brain failure).
type ConvertedNumbersToStrings<Arr extends readonly any[]> = {
[Index in keyof Arr]:
Arr[Index] extends number ? `${Arr[Index]}` : Arr[Index]
}
Mapped tuples tend to need a little help and the implementation is rough, but you'll get a result:
function convertNumbersToStrings<Arr extends readonly any[]>(arr: Arr)
: ConvertedNumbersToStrings<Arr>
{
return arr.map(x =>
typeof x === "number" ? x.toString() : x
) as ConvertedNumbersToStrings<Arr>;
}
const myArray = ["foo", 3.14, true] as const;
const out = convertNumbersToStrings(myArray);
// typeof out = readonly ["foo", "3.14", true]
Without the return type annotation, out
's type is inferred as any[]
.
英文:
Yes, it is possible (thanks to @Blackhole for correcting my Sunday night brain failure).
type ConvertedNumbersToStrings<Arr extends readonly any[]> = {
[Index in keyof Arr]:
Arr[Index] extends number ? `${Arr[Index]}` : Arr[Index]
}
Mapped tuples tend to need a little help and the implementation is rough, but you'll get a result:
function convertNumbersToStrings<Arr extends readonly any[]>(arr: Arr)
: ConvertedNumbersToStrings<Arr>
{
return arr.map(x =>
typeof x === "number" ? x.toString() : x
) as ConvertedNumbersToStrings<Arr>;
}
const myArray = ["foo", 3.14, true] as const;
const out = convertNumbersToStrings(myArray);
// typeof out = readonly ["foo", "3.14", true]
Without the return type annotation, out
's type is inferred as any[]
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论