Try   HackMD

[Advent of Typescript 2024] 7/25 (const assertion)

tags TypeScript

created: 2025/01/23

題目

https://www.adventofts.com/events/2024/7

const assertion 常數斷言

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"] for colors. 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 off as 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,可以看出兩個型別的不同。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

參考資料