Open13
TypeScriptの型
そもそもTypeScriptとは
TypeScriptとは、JavaScriptがベースとなっており変数や引数などに対して型(数値や文字型など)を付けることができる言語。
変数や関数の後に「:
」を付け、その後に任意の型を書く必要がある。
プリミティブ型 (primitive types)
基本的な型
// 文字列:string
let str: string = 'hello world';
// 数値:number
let num: number = 123;
// 大きい数値: bigint
let bignum: bigint = 1235467891234567n;
// 真偽値:boolean
let bool: boolean = true;
// 空の値:null
let n: null = null;
// 未定義の値:undefined
let ud: undefined = undefined
// 一意のデータ:symbol
let sym: symbol = symbol()
ユニオン型 (union type)
「いずれかの型」を表現するもの。
パイプ(こういうやつ⇒ | )で区切ることで、1つの要素に対して複数の型をつける。
// 文字列と数値を代入できる変数 ※es2020以降
let str_num: string | number
str_num = 'こんにちは'
console.log(str_num) // こんにちは
str_num = 123
console.log(str_num) // 123
リテラル型 (literal type)
プリミティブ型の特定の値だけを代入可能にする型。
もうこのデータしか受け付けません!!みたいなこと。
// Helloしか代入できない
let x: 1;
x = 1;
x = 100;
Type '100' is not assignable to type '1'.
配列型 (array type)
型名の後に[]を付けて宣言すると、その型しか挿入できない型ができる。
また、ユニオン型を使って複数の型が入る配列もできる。
// 数値の配列
let nums: number[] = [1,2,3];
// 文字列の型
let strs: string[] = ['a','b','c'];
// 色々な型の配列
let some: (string | number | boolean)[] = [1,'Hello',true];
オブジェクト型 (object type)
オブジェクトの形式で1つのプロパティに対して自由に型を宣言できる。
基本的にオブジェクト型に代入する値は宣言したプロパティの数だけデータを入れないとエラーになる。
// 名前と年齢のオブジェクトを指定する型
let userData: { name: string, age: number } = {
name: 'aaa',
age: 20
}
データ入れたくない場合
データ入れたくない場合はプロパティの後に「?」を付ける。
// エラーになる
let userData: { name: string, age: number, profile: string } = {
name: 'aaa',
age: 20,
}
// ↓
// エラーにならない
let userData: { name: string, age: number, profile?: string } = {
name: 'aaa',
age: 20,
}
関数の型の宣言 (function type declaration)
TypeScriptで関数を作成する際は、引数や戻り値にも型定義をする必要がある。
引数は引数の後に型を定義し、戻り値は引数のカッコの後に型を定義します。
// 関数の型宣言構文
type 型の名前 = (引数名: 引数の型) => 戻り値の型;
// 関数の定義
function sum(a: number, b: number): number{
return a + b;
}
// アロー関数
const sum = (a: number, b: number): number => x + y;
// デフォルトの値も設定可能で、引数が渡らなくても計算可能になります。
function sum2(a: number b: number = 1): number{
return a + b;
}
console.log(sum2(5)) // 6
// 戻り値が無い関数の場合はvoidを指定します。
const greet = (text: string): void => console.log(text)
簡略化
// 関数の型定義
type SumType = (a: number, b: number) => number
const sum: SumType = (a,b) => a + b;
ジェネリクス (generics)
主に関数の定義の時に使用され、型を関数使用時に自由に決められるようになる機能。
型も引数のように扱い、共通化できる。
// <>の中に型の情報が入る。
const arrGenerator = <T>(value: T, time: number): T[]{
return new Array(time).fill(value) // 配列をvalueのデータで埋め尽くす
}
console.log(arrGenerator<number>(1, 3)) //[1,1,1]
console.log(arrGenerator<string>('foo', 3)) //['foo','foo','foo']
コンポーネントの定義 (component)
//---------------------------------コンポーネント
const Hello: React.FC = () => {
return <h1>Hello Workd!!</h1>
}
export default Hello
//---------------------------------コンポーネントを利用
import Hello from './Hello'
const App: React.FC = () => {
return <Hello />
}
export default App
propsの定義
//---------------------------------コンポーネント
// propsの型
type Props = {
greet: string
}
// コンポーネント作成
const Hello: React.FC<Props> = (props) => {
return <h1>Hello {props.greet}</h1>
}
export default Hello
//---------------------------------コンポーネント利用
import Hello from './Hello'
const App: React.FC = () => {
return <Hello greet='World!!!'>
}
export default App
Childrenを定義
Childrenを定義する場合はReact.ReactNodeを定義。
//---------------------------------コンポーネント
// propsの型
type Props = {
greet: string,
children: React.ReactNode
}
// コンポーネント作成
const Hello: React.FC<Props> = (props) => {
return (
<>
<h1>Hello { props.greet }</h1>
<div>{ props.children }</div>
</>
)
}
export default Hello
//---------------------------------コンポーネント利用
import Hello from './Hello'
const App: React.FC = () => {
return <Hello greet='World!!!'>Its A My World!!!</Hello>
}
export default App //<h1>Hello World!!!</h1><div>Its A My World!!!</div>
関数を渡す
//---------------------------------コンポーネント
// propsの型
type Props = {
func: () => void
}
// コンポーネント作成
const Btn: React.FC<Props> = (props) => {
return <button onClick={ () => props.func }>ボタン</button>
}
export default Btn
//---------------------------------コンポーネント利用
import Btn from './Btn'
const App: React.FC = () => {
const greet = () => console.log("Hello World!!!")
return <Btn func={ greet } />
}
export default App
イベントの型定義
コンポーネント内でボタンのクリックイベントやselectタグのチェンジイベントの処理を分けて記述するときは、React専用のイベント型を定義する必要がある。
const App = () => {
// クリックイベントの定義
const handleClick = (event: React.MouseEvent<HTMLButtonElement,MouseEvent>) => {
console.log("Hello World")
}
return (
<>
<button onClick={handleClick}>ボタン</button>
</>
)
}
クリックイベントの以外のイベント型
onClick: (event: React.MouseEvent<HTMLInputElement>) => void // クリックイベント
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void // チェンジイベント
onkeypress: (event: React.KeyboardEvent<HTMLInputElement>) => void // キーボードイベント
onBlur: (event: React.FocusEvent<HTMLInputElement>) => void // 要素のフォーカスが外れた時
onFocus: (event: React.FocusEvent<HTMLInputElement>) => void // 要素のフォーカス時のイベント
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void // formのsubmit時のイベント
stateの型定義
// stateの定義
const [ state, setState ] = useState<string>('Hello')
// 型エイリアスを利用することもできる
type Users = {
name: string,
age: number
}
const [ users, setUsers ] = useState<Users[]>([
{ name: 'Taro', age: 20 },
{ name: 'Jiro', age: 17 }
])