Given an array, transform it into an object type and the key/value must be in the provided array.
給定一個陣列,將其轉換為物件型別,並且鍵和值必須來自所提供的陣列。
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
type result = TupleToObject<typeof tuple>
// expected { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
接下來,你的任務是讓下面的type cases測試通過:
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
const tupleNumber = [1, 2, 3, 4] as const
const sym1 = Symbol(1)
const sym2 = Symbol(2)
const tupleSymbol = [sym1, sym2] as const
const tupleMix = [1, '2', 3, '4', sym1] as const
type cases = [
Expect<Equal<TupleToObject<typeof tuple>, { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y' }>>,
Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1, 2: 2, 3: 3, 4: 4 }>>,
Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1, [sym2]: typeof sym2 }>>,
Expect<Equal<TupleToObject<typeof tupleMix>, { 1: 1, '2': '2', 3: 3, '4': '4', [sym1]: typeof sym1 }>>,
]
在這一關中,我們可以從以下幾個方向來思考:
我們將會用到:
T[number]
提取元組中的每個元素,將其作為物件的鍵和值。這個語法是用來遍歷數組或元組中的每個元素,並取回其型別。string
、number
和 symbol
,表示物件屬性鍵的有效類型。這將幫助我們確保生成的物件鍵符合 TypeScript 規定的鍵類型。Mapped Types 在第三關已經介紹過,可以回到第三關參考喔!
這次的挑戰可以透過一個簡單的 Mapped Types 來解決,我們會將 Tuple 的每個元素映射為物件中的鍵和值。
type TupleToObject<T extends readonly PropertyKey[]> = {
[P in T[number]]: P
};
細節分析:
T extends readonly PropertyKey[]
:限制 T 必須是 readonly PropertyKey[]
類型,即一個readonly的屬性鍵類型的元組。
[P in T[number]]
: 這部分是映射類型的語法,用來遍歷元組 T
中的每個元素。T[number]
會提取出元組中的每個元素的聯合類型。
[P in T[number]]: P
:定義了物件中的每一個屬性。對於 T
中的每一個元素 P
,生成一個鍵為 P
的屬性,該屬性的值也為 P
。
這樣,我們就能順利通過測試啦 🎉 😭 🎉
Tuple
(元組):
// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
// Initialize it incorrectly
x = [10, "hello"]; // Error
// ^? Type 'number' is not assignable to type 'string'.
// Type 'string' is not assignable to type 'number'.
Example: Mutable Tuple
let tuple: [string, number, boolean];
tuple = ["Hello", 42, true];
tuple[0] = "World"; // This is allowed
tuple[1] = 10; // This is allowed
Example: Readonly Tuple
let readonlyTuple: readonly [string, number, boolean];
readonlyTuple = ["Hello", 42, true];
// readonlyTuple[0] = "World"; // This will cause an error
// readonlyTuple[1] = 10; // This will cause an error
const assertion (as const):
*const*
assertions.const
in place of the type name (e.g. 123 as const
). When we construct new literal expressions with const
assertions, we can signal to the language that
"hello"
to string
)readonly
propertiesreadonly
tuples// Type '"hello"'
let x = "hello" as const;
// Type 'readonly [10, 20]'
let y = [10, 20] as const;
// Type '{ readonly text: "hello" }'
let z = { text: "hello" } as const;
T[number]:
用途: In TypeScript, T[number]
is a type that represents the union of all the types of the elements in the array (or tuple) T
.
T[number]
is an example of an indexed access type. When you have an array or tuple type T
, using T[number]
means you are accessing the type of any element within that array or tuple.範例:
const tuple = ['apple', 'banana', 'cherry'] as const;
type Tuple = typeof tuple; // ['apple', 'banana', 'cherry']
type ElementType = Tuple[number]; // 'apple' | 'banana' | 'cherry'
本次介紹了 Tuple to Object
的實作,下一關會挑戰First of Array
,期待再相見!