🌟

TypeScript入門(型の定義方法 1)

2022/08/24に公開

プリミティブ型

プリミティブとは、TypeScriptが扱うことの出来る基本的な値のこと
具体的な例としては、文字列、数値、巨大な数値、真偽値、null、undefinedなどがある

let str: string = 'Hello'; //文字列のみ
   str = 1; //Type 'number' is not assignable to type 'string'

let num: number = 1;
num = 'aaa'; //Type 'string' is not assignable to type 'number'.

let bigNum: bigint = 100n; //es2020以降

let bool: boolean = true;
bool = 1; //Type 'number' is not assignable to type 'boolean'.

let nullish: null = null;

let undefindeVal: undefined = undefined;

//リテラル型 https://jsprimer.net/basic/data-type/
let trueVal: true = true;
trueVal = 1; //Type '1' is not assignable to type 'true'.

//特定の型
let strHello: 'Hello' = 'Hello';
strHello = 'hello'; //Type '"hello"' is not assignable to type '"Hello"'.

ユニオン型

ユニオン型(union type)は、複数の型を組み合わせて「型Tまたは型U」のような、「または」の意味を表すことができる。
T | U というように、| を用いてユニオン型を表す。
先頭に|がある場合はそれは、無視される。

let strOrNum: string | number = 'Hello';
  strOrNum = 123;
  // strOrNum = true; //Type 'boolean' is not assignable to type 'string | number'.
  console.log(strOrNum); //123

  //リテラル型を結合
  let helloOrNumOrBool: 'Hello' | number | boolean = 'Hello'

配列とオブジェクトの型定義

#### 配列

let arry1: number[] = [1, 2, 3];
let arry2: string[] = ['a', 'b', 'c'];
let arry3: Array<number> = [1, 2, 3]; //ジェネリック型
let arry4: (string | number)[] = ['hello', 1]; //数値と文字列が混在した配列
let arry5: Array<string | number> = ['hello', 1]; //上と同じ意味

オブジェクト

const obj1: { name: string, age: number } = { name: 'Taro', age: 10 };
obj1.name = 18; //Type 'number' is not assignable to type 'string'.
obj1.addres; //Property 'addres' does not exist on type '{ name: string; age: number; }'.
//jsでは、undefinedが返ってくるところだが、tsではエラーとなる。

オブジェクトを含む配列

const users: { name: string, age: number }[] = [
    { name: 'Taro', age: 10 },
    { name: 'Jiro', age: 12 },
    { name: 'Hana', age: 14 },
    { name: 'Kumi' } // 'age' is missing in type '{ name: string; }' but required in type '{ name: string; age: number; }'.
  ]

型推論

TypeScriptでは型推論(type inference)によって型をある程度推定してくれる機能がある。
基本的には、明らかに型が分かるような場合の型定義は型推論に任せるようにする。

let str: string = 'Hello'; //明示的な型適宜
let str1 = 'Hello'; //tsに任せた型推論(ホバーで確認するとstring)

let obj = { name: 'Taro', age: 10 }; //tsに任せた型推論(ホバーで確認するとname->string,age->number)

constで宣言した場合は、リテラル型となる。

const bye = 'bye'; //const bye: "bye"
const num = 123; //const num: 123

独自の型定義(type)

TypeScriptでは、type文を用いて型に別名を付けることができる。これを 型エイリアス(type alias) と呼ぶ。
パスカルケースで記述を行う。

type User = {
  name: string,
  age: number
}
const user: User = { name: 'Taro', age: 10 };

  //個別に型を定義することもできる
  type UserName = string;
  type UserAge = number;
  type UserGender = "man" | "woman" | "others";
  //上の3つをまとめて
type UserProfile = {
  name: UserName,
  age: UserAge,
  gender: UserGender
}

const userProfile: UserProfile = {
  name: 'Taro',
  age: 10,
  gender: 'man'
}

関数の型定義

####引数の型定義

const sum1 = (x: number, y: number) => x + y;
console.log(sum1(1, 2)); //3
console.log(sum1(1)); //Expected 2 arguments, but got 1.

jsでは、引数の個数が定義時と実行時に合わなくても問題ないが、tsではエラーとなる。
その場合は、下記の二通りのエラー回避方法がある。

//デフォルト値の設定
const sum1 = (x: number, y: number = 1) => x + y;
console.log(sum1(1)); //2
// ?を付ける
const sum1 = (x: number, y?: number) => x + y;
console.log(sum1(1)); //Nan

? を付けると number | undefined となるので、計算式には使えない。

戻り値の定義型

引数の () の後に、: を付けて型を定義する。

const sum2 = (x: number, y: number): number => x + y;
console.log(sum2(1, 2)); //3

戻り値がない関数

const sum3 = (x: number, y: number): void => {
    const innerSum = x + y;
  };

typeを使った関数の型定義

typeで型を定義して、関数名の後に : と型を入れる

type Sum = (x: number, y: number) => number;
const sum4: Sum = (x, y) => x + y;

ジェネリクス

ジェネリクスとは、型引数(type parameters)を受け取る関数を作る機能のことを指す。
<T>(大文字一文字)で可変可能な型を定義し、関数実行時に型を定義する。
関数実行時までどの型になるかわからない。

const repeat = <T>(value: T, times: number): T[] => {
  return new Array(times).fill(value);
}
const numArry = repeat<number>(10,3);
console.log(numArry)

関数コンポーネントの型定義

const Hello: React.FC = () => {
  return (
    <h1>Hello TypeScript</h1>
  )
}	

Propsの型定義

type で定義して、型パラメーターで渡す。

type HelloProps = {
  hello: string;
}
const Hello: React.FC<HelloProps> = (props) => {
  return (
    <h1>{props.hello}</h1>
  )
}

type で定義して、propsへ直接渡す。

type HelloProps = {
  hello: string;
  children: React.ReactNode;
}
const Hello = (props: HelloProps) => {
  return (
    <h1>{props.hello} {props.children}</h1>
  )
}	

childrenを渡して、型を定義する

React18からは、明示的に children を定義する必要がある。

type HelloProps = {
  hello: string;
  children: React.ReactNode;
}
const Hello: React.FC<HelloProps> = (props) => {
  return (
    <h1>{props.hello} {props.children}</h1>
  )
}	

###propsに関数が渡ってきた場合の型定義

type FnProps = {
  fn: (text: string) => void;
}
export const Btn: React.FC<FnProps> = (props) => {
  return (
    <button onClick={() => props.fn('TypeScript')}>ボタン</button>
  )
}
f

Discussion