JavaScriptやTypeScriptで出てくる記述の意味や名称など

JavaScriptやTypeScriptで「意味はわかるけど名称がパッとわからない」ものをまとめてみました。

## ??（Null合体演算子）
クエスチョンマーク（はてなマーク）が2つ続いたやつはNull合体演算子です。
左辺がnullかundefinedの場合は右の値を返してそれ以外の場合は左の値を返します。

```TypeScript
const val1 = null;
console.log(val1 ?? '値はnullです') // 値はnullです

const val2 = 'test';
console.log(val2 ?? '値はnullです') // test
```

## ?.（オプショナルチェイニング）
?（はてなマーク）と.（ドット）が続いたやつはオプショナルチェイニング（オプショナルチェーン）です。
オブジェクトでプロパティにアクセスする際に、中間のプロパティがなくてもエラーではなくundefinedで返してくれます。

### オプショナルチェーンを使用しない場合
```TypeScript
const student = {
    name: 'Taro',
}

console.log(student.name) // Taro
console.log(student.age) // undefined
console.log(student.club.name) // Cannot read properties of undefined (reading 'name') 
```

### オプショナルチェーンを使用する場合
```TypeScript
const student = {
    name: 'Taro',
}

console.log(student.name) // Taro
console.log(student.age) // undefined
console.log(student.club?.name) // undefined
```

### ...（スプレッド構文）
.（ドット）が3つ続いたやつはスプレッド構文です。
配列やオブジェクトを展開してくれます。

```TypeScript
// 配列を展開
const array1 = [1, 2, 3]
console.log(...array1) // 1, 2, 3

// 配列のコピー
const array1 = [1, 2, 3]
const array2 = [...array1]
console.log(array2) // 1, 2, 3

// 配列の結合
const array1 = [1, 2, 3]
const array2 = [4, 5, 6]
const array3 = [...array1, ...array2]
console.log(array3) // 1, 2, 3, 4, 5, 6

// 関数の引数に渡す
const sumValue = (value1, value2) => {
    return value1 + value2
}
const array1 = [5, 10]
console.log(sumValue(...array1)) // 15
```

## ?（オプションパラメーター）
TypeScriptのinterfaceとかtypeのプロパティについてるはてなマークはオプションパラメーター（オプショナルプロパティ）です。
TypeScriptで使用できます。
関数の引数やインターフェースのプロパティを省略可能になります。

### オプションパラメーターを使用しない場合
```TypeScript
interface Student {
    name: string
    age: number
    club: string
}

const student: Student = {
    name: 'taro',
    age: 16,
}
// プロパティ「club」が存在しないためエラーとなる
// Property 'club' is missing in type '{ name: string; age: number; }' but required in type 'Student'.
```

### オプションパラメータを使用する場合
```TypeScript
interface Student {
    name: string
    age: number
    club?: string
}

const student: Student = {
    name: 'taro',
    age: 16,
}
// オプションパラメーターを使用することでプロパティ「club」が存在しなくてもエラーにならない
```

## \<T\>（ジェネリクス）
大なり小なりの記号の中に型があるやつはジェネリクス（Generics）です。
配列の型を指定するときや、型を動的に変えたい場合に使用します。
ReactのuseStateをイメージしやすいと思います。

```TypeScript
// 配列の型定義
const array: Array<string> = ['Taro', 'Jiro', 'Saburo']
array[4] = 'Goro'
array[5] = 1 // string型の配列にnumber型を入れようとしているのでエラーになる。Type 'number' is not assignable to type 'string'.
```

```TypeScript
// 動的に型を変更
type Test<T> = {
    (val1: T, val2: T): T
}

const test1: Test<string> = (val1, val2) => {
    return val1 + val2
}
console.log(test1('Taro', 'Jiro')) // TaroJiro


const test2: Test<number> = (val1, val2) => {
    return val1 + val2
}
console.log(test2(1, 2)) // 3
```

```React
const [name, setName] = useState<string>('')
const [age, setAge] = useState<number>(0)
```

## !!（否定の論理演算子）
「!!value」のような感じで主に変数の前にビックリマークを2つ並べたものは二重否定の論理演算子です。

!を1つつけると否定となりなるのでtrueの場合はfalse、falseの場合はtrueになります。
それを2つ並べるので、trueの場合はtrue、falseの場合はfalseになります。

無駄と思われるかもしれませんが、古いブラウザはundefinedをfalseと扱ってくれないことがあったため、わざわざこんなことをしていました。

```TypeScript
if (!!value) {
  console.log(value)
}

!!value && console.log(value)
```

## 変数の後ろに!（非nullアサーション演算子）
変数の後に!がついているのは非nullアサーション演算子(Non-Null Assertion Operator)です。

コンパイラに対して「変数がnullでなくundefinedでない」と伝えるものになります。

下記の例だとsampleFunc の引数paramはオプショナルのため、param.lengthとかくと'param' is possibly 'undefined'と怒られます。

```TypeScript
const sampleFunc = (param?: string) => {
  return param.length; // 'param' is possibly 'undefined'
}
```

そこで、下記のようにparam!.lengthと書くと「paramはnullでなくundefinedでない ＝ string型である」とコンパイラに明示できるので、エラーにはなりません。

```TypeScript
const sampleFunc = (param?: string) => {
  return param!.length
}
```