TypeScriptで基本的と思われる新しく知った知識

6 回閲覧されました
みなさんこんにちは、jonioです。
現在TypeScriptを習得していますが恐らく基本的と思われる内容で新しく知った知識をメモとして残します。
随時追加します。
目次
Laravelの無料学習サイトを作りました
Laravelを勉強したい人向けの無料の学習サイトを作りました。
ここからリンクに飛べますのでぜひ利用してください。
前提条件
Vue.js3に使っていますのでReact.js(Next.js)で使うと使い方が変わるかもしれません。
interface
親から渡されたデータ(props)がある場合は型定義をしないといけないですがこの時に使います。
下記の書き方をします。
interface User {
id: number;
name: string;
}
defineProps<{
user: User
}>();
7行目の「user」は親から渡されたデータです。
「user: User」で親から渡されたデータの「user」を「User」と定義しています。
定義をどう決めているのかが1行目〜3行目です。
idはnumber(数値)の指定をしてnameはstring(文字)の指定をしています。
型注釈
変数の型を指定するのに使います。
下記の記述をしたとします。
const url = ref<string>('');
「<string>(‘ ‘)」の「string」はurlの型を指定しています。
「(‘ ‘)」は初期値です。
今の記述では初期値が空ですが場合によっては値が空になったりならなかったりする場合があります。
そんな時は下記の書き方をします。
const url = ref<string | null>(null);
「<string | null>」の記述をすればいいです。
型の指定は関数に対してもできます。
下記の記述をしたとします。
function greet(name: string): string {
return `こんにちは、${name}さん!`
}
「name: string」はnameの型の指定をしています。
「(name: string): string」の「: string」のstringは関数の返り値の型の指定をしています。
リテラル型
文字だけ・数値だけ・真偽値だけなど特定の型のみの構成で型定義をしている時はリテラル型になります。
例えば下記の書き方をします。(今回は文字列リテラル型です)
type Day = 'Mon' | 'Tue' | 'Wed' | 'Thu' | 'Fri' | 'Sat' | 'Sun'
Any型
変数に対してどんな型でも設定できるようになります。
下記コードで考えます。
let value: any;
value = 123;
console.log(value); // 結果は「123」
value = "hello";
console.log(value); // 結果は「hello」
value = { a: 1 };
console.log(value.a); // 結果は「1」
型のチェックがなくなるのでどんな値でも代入できるようになります。
型定義の意味がなくなるので絶対に使わないといけない時以外は使うべきではないです。
ユーティリティ型
ユーティリティ型はTypeScriptが用意している使うと便利な型みたいです。
Record
その中のRecordは下記の書き方をします。
Record<キーの型, 値の型>
具体的なコードを見ていきます。
<template>
<div>
<p>Aさんの得点: {{ scores.A }}</p>
<p>Bさんの得点: {{ scores.B }}</p>
<p>Cさんの得点: {{ scores.C }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const scores = ref<Record<'A' | 'B' | 'C', number>>({
A: 85,
B: 92,
C: 78,
})
</script>
「Record<キーの型, 値の型>」の「キーの型」は「’A’ | ‘B’ | ‘C’」です。
「キーの型」は使うことができる変数を指定しているイメージです。
この場合「使うことができる変数はAかBかCのみ」という意味です。
「Record<キーの型, 値の型>」の「値の型」は変数(A・B・Cのこと)に対する型の指定です。
今回はnumber(数値)の指定をしています。
下記はオブジェクトになっています。
{
A: 85,
B: 92,
C: 78,
}
TypeScriptを使わない書き方をすると下記になります。
const scores = ref({
A: 85,
B: 92,
C: 78
});
このままだと型が分からないですがこれに型をプラスして簡潔に書いた書き方がRecordで下記になります。
const scores = ref<Record<'A' | 'B' | 'C', number>>({
A: 85,
B: 92,
C: 78,
})
変数に対する型の指定と値の設定を同時に行ってると言えます。
ReturnType
関数の「戻り値の型」を自動で取得できます。
ReturnTypeは下記の書き方をします。
ReturnType<typeof 関数名>
これだけでは理解ができないので下記のサンプルコードで考えます。
function getMessage(): string {
return "こんにちは!";
}
type MessageType = ReturnType<typeof getMessage>;
1行目のgetMessageメソッドの返り値はstringに設定していますがstringと同じ型である変数を設定しているのが5行目です。
「MessageType」の方はstringになります。
non-null assertion
下記の記述をしたとします。
let countdownInterval: ReturnType<typeof setInterval> | null = null
countdownStartTimer = setTimeout(() => {
countdownValue.value = 7
countdownVisible.value = true
countdownInterval = setInterval(() => {
countdownValue.value --
if (countdownValue.value <= 0) {
clearInterval(countdownInterval)
}
}, 1000)
}, 8000)
1行目の「countdownInterval」は定義にnullが入っているので「countdownInterval = null」の可能性があり12行目のclearIntervalでnullの場合の警告が出る可能性があります。
それを防ぐ為に下記の記述をします。
clearInterval(countdownInterval!)
countdownIntervalの後ろに「!」を付けることでcountdownIntervalはnullの場合はないことを宣言します。
non-null assertionと言いますがこれで警告は出なくなります。
ジェネリックス関数
下記の記述をしたとします。
const wrap = <T>(v: T): T => {
return v;
};
通常型は先に決めますが「<T>」は型を変数みたいに後から指定ができるようになるという意味です。
こういう関数をジェネリックス関数と言います。
wrap関数を使った例のコードで見ていきます。
const wrap = <T>(v: T): T => {
return v;
};
const a = wrap<number>(123);
const b = wrap<string>('abcde');
const c = wrap('hi');
5行目は型を数値と指定して6行目は型を文字と指定して7行目は型の指定をしていないですが引数から型をstring(文字)に指定しています。(型推論)
独自の型の定義
TypeScriptが用意している型とは別に自分で型を作ることができます。
下記の記述をします。
type XY = {
x: string;
y: number;
};
こう記述をするとXYの型はオブジェクトになりxの型はstringでyの型はnumberに指定することができます。
使用する時は例えば下記の書き方をします。
const point1: XY = {
x: '横方向',
y: 100,
};
?:
例えば下記の記述があったとします。
type XY = {
x?: string;
y: number;
};
「x: string」ではなく「x?: string」になっていますがこの時はxは存在しても存在しなくてもどっちでもいいという意味です。
下記みたいな意味になります。
string | undefined