DAY 16
3
Modern Web

# 強型闖入DenoLand[15] - 型別補充

• 元組 (Tuple)
• 列舉 (Enum)
• Never
• Unknown

## 元組

``````// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
``````

``````x[0] = "hello";
x[1] = 10;
``````

``````// Initialize it incorrectly
x = [10, "hello"]; // Error
``````

``````// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
// OK
console.log(x[0].substring(1));
``````

`substring()` 用於分割字串，舉例:

``````const str = 'Mozilla';

console.log(str.substring(1, 3));
// expected output: "oz"

console.log(str.substring(2));
// expected output: "zilla"
``````

``````let x: [string, number];
x = ["hello", 10];
x[2] = {};
``````

``````x[2] = {};// NOPE
x[2] = 12;// OK
x[2] = "Ian";// OK
``````

## 列舉

``````enum month {
JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}
``````

``````console.log(month["JAN"] === 0); // true
console.log(month["FEB"] === 1); // true
console.log(month["JUL"] === 6); // true
``````

``````console.log(0 === month["JAN"]); // true
``````
• 知識點: 相等 `==` 與全等 `===`、自動轉型

請參考本日的延伸閱讀。

``````enum month {
JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}
``````

``````console.log(month["JAN"] === 1); // true
console.log(month["FEB"] === 2); // true
console.log(month["JUL"] === 7); // true
``````

## Never

`Never` 型別用於以下情況:

• 沒有回傳值的函式，像是無窮迴圈。
• 一天到晚出錯的函式
``````// Function returning never must not have a reachable end point
function error(message: string): never {
throw new Error(message);
}

// Inferred return type is never
function fail() {
return error("Something failed");
}

// Function returning never must not have a reachable end point
function infiniteLoop(): never {
while (true) {}
}
``````

`Void` 代表的是沒有回傳值的函式，而 `Never` 會用於表示本就不會有回傳值，或是會拋出錯誤的函式:

``````function errMsg(msg: string): never {
throw new Error(msg);
}
``````

``````let value :never;
value = 123;// NOPE
value = ((msg: string)=>{ throw new Error(msg); })('Ian')// OK
``````

## Unknown

`Unknown``Any` 型別有一個共同點，就是: 所有類型都可以被歸類成 `Unkown`, `Any`

``````let value: unknown = 3;
value = "Ian";
value = undefined;
value = null;
value = true;
``````

### 賦值限制

``````let value: unknown;
let value1: unknown = value;   // OK
let value2: any = value;       // OK
let value3: number = value;   // Nope
let value4: boolean = value;    // Nope
let value5: string = value;    // Nope
// ...
``````

### 限制操作

``````let value: unknown;
let value2: any;
value.substring();
value2.substring();
``````

``````Object is of type 'unknown'.
``````