手を動かしながら学ぶ TypeScript Part 1 -- 基礎的な型
Tags: typescript
Published: 2022-02-20 23:13:50



基本的な string や number の他にもかなりあったので並べていく。

## 参考

手を動かしながら学ぶ TypeScript
by SmartHR
SECTION-006 基礎的な型
P.26 ~

https://www.amazon.co.jp/%E6%89%8B%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6-TypeScript-%E6%B8%A1%E9%82%89%E6%AF%94%E5%91%82%E6%A8%B9-ebook/dp/B09KZJXDN1

---

## string, number

P.26

```ts
const name: string = 'Aki'
const age: number = 20
```

このように 変数名: 型 = 値
として型を当てられる。これを型アノテーションというらしい。
number には小数点もマイナスもインフィニティも入る。


---

## object 

```ts
const dog : {
  name: string,
  age: number,
} = {
  name: 'Aki',
  age: '300',
}
```

オブジェクトはこのように初期値を入れる。
なかなか奇妙な形で慣れないが、よく見ると

```ts
const dogAge: number = 3
const dog: { age:number } = { age: 3}
```

`:number` のところを `{age:number}` にして
`3` のところを `{age:3}` にしているだけなのがわかる。


```ts
obj.ts:15:3 - error TS2322: Type 'string' is not assignable to type 'number'.

15   age: '300',
     ~~~

  obj.ts:12:3
    12   age: number,
         ~~~
    The expected type comes from property 'age' which is declared here on type '{ name: string; age: number; }'
```

違う type のデータを入れると、ちゃんと教えてくれる。

---

## boolean -- '', 0, undefined, は入らない。

```ts
const isOpen: boolean = true
```

boolean 型は true か　false が入る。

```ts
tsc bool.ts        
bool.ts:3:7 - error TS2322: Type 'string' is not assignable to type 'boolean'.

3 const empty: boolean = ''
        ~~~~~

bool.ts:4:7 - error TS2322: Type 'number' is not assignable to type 'boolean'.

4 const zero: boolean = 0
        ~~~~

bool.ts:5:7 - error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.

5 const undefined: boolean = undefined
        ~~~~~~~~~

bool.ts:5:28 - error TS2448: Block-scoped variable 'undefined' used before its declaration.

5 const undefined: boolean = undefined
                             ~~~~~~~~~

  bool.ts:5:7
    5 const undefined: boolean = undefined
            ~~~~~~~~~
    'undefined' is declared here.


Found 4 errors.
```

空の文字列、数値のゼロ、未定義は false と思われがちだが
ts では boolean にそれらは入れられない。

---

## 配列

```ts
const list: number[] = [0, 1, 2, ]
list.push(99)
list.push('text')
```

配列か配列でないかではなく
数値の配列か、文字列の配列かなどを設定できる。

```ts
tsc arr.ts 
arr.ts:3:11 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

3 list.push('text')
            ~~~~~~
```

数値の配列に文字列を追加するとエラーが出る。


```ts
const numList: Array<number> = [1, 2, 3, false, ]
```

number[] は Array<Number> という書き方もできる。

---

## null -- strict でも 入る

```ts
const text: string = 'text'
const undefString: string = undefined
const nullString: string = null
```

文字列型の変数に undefined と null を入れるコードを作る

tsconfig.json/compileOptions/strict/strictNullChecks

```json
{
  "compilerOptions": {
   
    "target": "es5", 
    /* Strict Type-Checking Options */
    "strict": true,                                 /* Enable all strict type-checking options. */

    "strictNullChecks": true,                    /* Enable strict null checks. */
```

ここの設定を true にしていれば入れないはずだが...
通ってしまう。謎。

```ts
let text: string = 'text'
text = undefined
text = null
```

代入でも通ってしまう。


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4z5bcky28sim30quso1.png)

strict が false だと null の vscode の警告は消える。

---

## 関数

TS で関数かくと
この関数が文字列型で、引数も文字列型で、戻り値も文字列型で、って三箇所書く必要がある

しかし、interface や type を型引数としてとれば読みやすくなる

https://qiita.com/NeGI1009/items/a98c6a76b0c4f3bc18b3#%E9%96%A2%E6%95%B0%E3%81%AE%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%AD%E3%83%BC%E3%83%89

```ts
type hoge:string;

export const foo:hoge => { ... }
```

こんな風に 関数名:関数の型 として使える


---

## ReadOnly

```ts
const baby : {
  name: string,
  weightGrams: number,
} = {
  name: "Taro",
  weightGrams: 300,
}

baby.name = 'smile'
```

型をつけて設定しても、オブジェクトの中身は書き換えられてしまう。
書き換えられないようにしたい時は readonly を 変数の前につければ
上書きできないようにできる。

```ts
const woman : {
  readonly name: string,
  age: number,
} = {
  name: 'Aki',
  age: 25,
}

woman.age = 80
woman.name = 'Teru'
```

コンパイルすると

```ts
tsc ro.ts
ro.ts:20:7 - error TS2540: Cannot assign to 'name' because it is a read-only property.

20 woman.name = 'Teru'
```

name は read-only だから再代入できないとエラーになってくれる。

---

## interface -- object で使える型のプロトタイプ。

```ts
interface Person {
  name: string,
  power: number,
}

const kaede: Person = {
  name: 'kaede',
  power: 70,
}
```

型のクラスを作って、それを使って変数を定義できる。

```ts
function App() {
  interface cat {
    color: string;
    weight: number;
  }
  const Tama:cat = {
    color: 'white',
    weight: 5000,
  }
  return (
    <div>
      <h2>{Tama.weight}</h2>
    </div>
  );
}
```

こうやって interface で使う型たちを定義して
オブジェクトをその interface の型にそって作成して
作成されたオブジェクトにアクセスする。
これが基本的な流れ。

---

## type オブジェクト

https://zenn.dev/luvmini511/articles/6c6f69481c2d17#2-3.-%E6%8B%A1%E5%BC%B5

基本的な使い方は　interface と同じ。

中身を追加できない、interface より厳密な型定義。

ミスで違うものを後から入れることがないのがバグを産みにくいらしい。

現在のチームでもこれを使っている