TypeScript
created: 2025/01/23
https://www.adventofts.com/events/2024/7
const createRoute = <Route extends string[]>(author: string, route: Route) => ({
author,
route,
createdAt: Date.now(),
});
// 希望丟入的陣列可以正確地得到裡面的型別,而不是其單純的表層型別
const oneMill = createRoute('💨Dasher', ['Atherton', "Scarsdale", "Cherry Hills Village"]).route;
type t0_actual = typeof oneMill; // => string[] => 希望可以得到 ['Atherton', "Scarsdale", "Cherry Hills Village"] 而不是表層的 string[]
type t0_expected = [ // => ['Atherton', "Scarsdale", "Cherry Hills Village"]
'Atherton',
"Scarsdale",
"Cherry Hills Village"
];
type t0 = Expect<Equal<t0_actual, t0_expected>>;
這裡在 GitHub 找到其他人的答案才知道怎麼寫…竟然有這種寫法:
const createRoute = <const Route extends string[]>(author: string, route: Route) => ({
author,
route,
createdAt: Date.now(),
});
然後根據這個 stackoverflow: A "const" assertion error typescript with string array 中的回覆:
If you write
const colors = ["white", "red", "blue"] as const;
then the compiler infers the type
readonly ["white", "red", "blue"]
forcolors
. The compiler knows the value and position of each member of that array, and it won't let you change any of that. […]
On the other hand, if you leave offas const
,
const colors = ["white", "red", "blue"];
then the compiler infers string[]
for colors
. It's just an array of strings of unknown quantity, value, or order.
所以想要讓 TypeScript 一定要從陣列裡面的值推導其型別,而不是上層的型別,就可以用 as const
。
從 TS Playground 可以實際 hover testList
以及 testListTwo
,可以看出兩個型別的不同。