# リテラル型

リテラルはJavaScriptのプリミティブである値そのものです。

## 文字列リテラル

型として文字列リテラルを使用できます。例えば：

```typescript
let foo: 'Hello';
```

ここでは`foo`という名前の変数を作成しました。それに代入されるリテラル値は`'Hello'`のみを許可します。これは以下のとおりです：

```typescript
let foo: 'Hello';
foo = 'Bar'; // Error: "Bar" is not assignable to type "Hello"
```

それらは単独ではあまり使い所がありませんが、ユニオン型で結合して、強力な(そして便利な)抽象化を作成することができます。

```typescript
type CardinalDirection =
    | "North"
    | "East"
    | "South"
    | "West";

function move(distance: number, direction: CardinalDirection) {
    // ...
}

move(1,"North"); // Okay
move(1,"Nurth"); // Error!
```

## その他のリテラル型

TypeScriptは`boolean`と`number`リテラル型もサポートしています。

```typescript
type OneToFive = 1 | 2 | 3 | 4 | 5;
type Bools = true | false;
```

## 推論

かなり一般的に`Type string is not assignable to type "foo"`というエラーを受け取ります。次の例はこれを示しています。

```typescript
function iTakeFoo(foo: 'foo') { }
const test = {
  someProp: 'foo'
};
iTakeFoo(test.someProp); // Error: Argument of type string is not assignable to parameter of type 'foo'
```

これは、`test`が`{someProp: string}`型であると推定されるためです。この問題を解決するには、シンプルな型アサーションを使用して、TypeScriptに以下のようにリテラルを推測させます。

```typescript
function iTakeFoo(foo: 'foo') { }
const test = {
  someProp: 'foo' as 'foo'
};
iTakeFoo(test.someProp); // Okay!
```

あるいは、型アノテーションを使うことで、宣言した時点でTypeScriptが正しい型を推論するのを助けることができます。

```typescript
function iTakeFoo(foo: 'foo') { }
type Test = {
  someProp: 'foo',
}
const test: Test = { // Annotate - inferred someProp is always === 'foo'
  someProp: 'foo' 
}; 
iTakeFoo(test.someProp); // Okay!
```

## ユースケース

文字列型の有効な使用例は次のとおりです。

### 文字列ベースの列挙型

[TypeScript enumsは数字ベースです](https://typescript-jp.gitbook.io/deep-dive/type-system/enums)。上記の`CardinalDirection`の例のようにユニオン型の文字列リテラルを使用して文字列ベースの列挙型を模倣することができます。次の関数を使って`Key:Value`構造体を生成することさえできます：

```typescript
/** Utility function to create a K:V from a list of strings */
function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {
  return o.reduce((res, key) => {
    res[key] = key;
    return res;
  }, Object.create(null));
}
```

そして、`keyof typeof`を使ってリテラル型の合成を生成します。完全な例を次に示します。

```typescript
/** Utility function to create a K:V from a list of strings */
function strEnum<T extends string>(o: Array<T>): {[K in T]: K} {
  return o.reduce((res, key) => {
    res[key] = key;
    return res;
  }, Object.create(null));
}

/**
  * Sample create a string enum
  */

/** Create a K:V */
const Direction = strEnum([
  'North',
  'South',
  'East',
  'West'
])
/** Create a Type */
type Direction = keyof typeof Direction;

/** 
  * Sample using a string enum
  */
let sample: Direction;

sample = Direction.North; // Okay
sample = 'North'; // Okay
sample = 'AnythingElse'; // ERROR!
```

### 既存のJavaScript APIのモデリング

例えば [CodeMirrorエディタには`readOnly`オプションがあります](https://codemirror.net/doc/manual.html#option_readOnly)。これは、`boolean`またはリテラル文字列`nocursor`(有効値: true、false、"nocursor")です。それは次のように宣言することができます：

```typescript
readOnly: boolean | 'nocursor';
```

### ユニオン型の区別

これは[本の後方](https://typescript-jp.gitbook.io/deep-dive/type-system/discriminated-unions)で説明します。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://typescript-jp.gitbook.io/deep-dive/type-system/literal-types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
