1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypeScriptの基本的な文法・型

Last updated at Posted at 2023-05-31

はじめに

私がまとめたTypeScriptに関する記事一覧になります。もし興味がありましたらご覧になってください。

今回は、TypeScriptの基本的な文法・型についての記事になります。

TypeScriptにおける型の階層構造

A の型の値が B の型に代入可能なとき、「A は B のサブタイプ」で「B は A のスーパータイプ」という関係にある。

TypeScript の型のスーパータイプ / サブタイプの関係は以下のようになっている。
スクリーンショット (1218).png
unknown はすべての型のスーパータイプであり、never はすべての型のサブタイプである。

なおこういった場合、unknown のような存在をトップ型(top type)と呼び、never のような存在をボトム型(bottom type)と呼ぶ。

型の階層構造が上記のようになっているということは以下のように代入可能ということ。

index.ts
const a: 'hello' = 'hello'; // String Enum type ('hello' type)
const b: string = a; // String type
const c: any = b; // Any type
const d: unknown = c; // Unknown type

基本的な型

any

  • any型はどんな型でも代入を許す
  • any型は型チェックされない
  • 型推論できない変数は暗黙的にany型になる
  • サバイバルTypeScript any型
let value: any;
value = 1; // OK
value = "string"; // OK
value = { name: "オブジェクト" }; // OK

// Parameter 'name' implicitly has an 'any' type.
function hello(name) {
  console.log(`Hello, ${name.toUpperCase()}`);
}

hello(1); // name.toUpperCase is not a function

unknown

  • unknown型は型安全なany型
  • unknown型の値は具体的な型へ代入不可
  • unknownと型の絞り込み(型ガード、型ガード関数)
  • サバイバルTypeScript unknown型
let value: unknown;
value = 1; // OK
value = "string"; // OK
value = { name: "オブジェクト" }; // OK

const value: unknown = 10; 
const int: number = value; // NG.

// 型ガード
const value: unknown = "";
if (typeof value === "string") {
  // ここブロックではvalueはstring型として扱える
  console.log(value.toUpperCase());
}

// 型ガード関数
function isObject(value: unknown): value is object {
  return typeof value === 'object' && value !== null;
}
const value: unknown = { a: 1, b: 2 };
// 型ガード
if (isObject(value)) {
  // ここでは、valueはobject型として扱える
  console.log(Object.keys(value));
}

boolean

const isOk: boolean = true;
const isNg: boolean = false;

string

  • ダブルクォートでもシングルクォートでもまったく同じ文字列型
  • テンプレートリテラル(バッククォート`で囲んだ文字列)
  • サバイバルTypeScript string型
const message: string = "Hello";

const count = 10;
console.log(`現在、${count}名が見ています。`);

number

  • 整数と少数の区別がない
  • 2進数、8進数、16進数
  • 数値の区切り文字(numeric separators)
  • 特殊な数値(NaNとInfinity)
  • サバイバルTypeScript number型
const integer: number = 123;
const decimal: number = 1.23;

0b1010 // 2進数
0o755 // 8進数
0xfff // 16進数

100_000_000 // 1億

const price = parseInt("百円"); //NaN
const infinity = 1 / 0; // Infinity

bigint

  • 数値型(2の53乗)よりも大きな整数を扱えるプリミティブ型
  • bigint型のリテラルは整数値の末尾にn
  • 計算速度はbigintよりも通常の数値(number)の方が高速
  • サバイバルTypeScript bigint型
const x: bigint = 100n;

literal

  • リテラル型はstring、number、booleanの3種類の型で作成が可能
  • リテラル型はマジックナンバーやステートの表現に用いられられる。その際、ユニオン型と組み合わせることが多い
  • サバイバルTypeScript リテラル型
const isTrue: true = true;
const num: 123 = 123;
const str: "foo" = "foo";

let num: 1 | 2 | 3 = 1;

object

let profile: {name: string} = { name : "Hiro" };
profile = {birthday: 1912} // エラーが発生。

array

let array: number[];
array = [1, 2, 3];

let array: Array<number>;
array = [1, 2, 3];

tuple

function tuple() {
  //...
  return [1, "ok", true];
}

const list: [number, string, boolean] = tuple();

null

const x: null = null;

console.log(typeof null); // object

undefined

  • 未定義を表すプリミティブな値
  • 変数に値がセットされていないとき、戻り値が無い関数、オブジェクトに存在しないプロパティにアクセスしたとき、配列に存在しないインデックスでアクセスしたときにundefinedが返る
  • サバイバルTypeScript undefined型
let name;
console.log(name); //undefined

function func() {}
console.log(func()); //undefined

const obj = {};
console.log(obj.name); //undefined

const arr = [];
console.log(arr[1]); //undefined

void

function print(message: string): void {
  console.log(message);
}

never

  • 「値を持たない」を意味するTypeScriptの特別な型
  • 値を持たないとは、『例外が必ず発生する関数の戻り値』や『終了しない関数(無限ループ)の戻り値』
  • never型には何も代入できない
  • never型はどんな型にも代入できる
  • サバイバルTypeScript never型
function throwError(): never {
  throw new Error();
}

function forever(): never {
  while (true) {} // 無限ループ
}

const foo: never = 1; // NG

const nev = 1 as never;
const a: string = nev; // 代入OK
const b: string[] = nev; // 代入OK

type alias(型の別名)

// プリミティブ型
type Str = string;
// リテラル型
type OK = 200;
// 配列型
type Numbers = number[];
// オブジェクト型
type UserObject = { id: number; name: string };
// ユニオン型
type NumberOrNull = number | null;
// 関数型
type CallbackFunction = (value: string) => boolean;

intersection(交差)

  • T & U のように書き、『T型でもありながらU型でもある』を意味する型
  • 『オブジェクト型を活用した新しい型を作る』という用途で使われる
  • サバイバルTypeScript intersection型
// 既存の型を組み合わせる

type RedColor = {
  red: number;
};

type BlueColor = {
  blue: number;
};


// [RedColor]と[BlueColor]を組み合わせる
type RedColorAndBlueColor = RedColor & BlueColor;

const PurpleColor: RedColorAndBlueColor = {
  red: 50,
  blue: 50,
};

union(合併)

// 複数の型を許容する

let value: number | string = 1;
value = "foo";
value = 2;

symbol

  • プリミティブ型の一種で、その値が一意になる値
  • シンボルはシンボル名が同じであっても、初期化した場所が違うとfalse
  • サバイバルTypeScript symbol型
const s: symbol = Symbol();

const s1 = Symbol("foo");
const s2 = Symbol("foo");
console.log(s1 === s1); // true
console.log(s1 === s2); // false

enum(列挙型)

enum Position {
  Top = 1, // 1
  Right, // 2
  Bottom, // 3
  Left, // 4
}

型アサーション

  • 式 as 型という構文で、その式の型を強制的に変えるという意味
  • 『値の変換』ではなく、TypeScriptコンパイラが認識する『型』だけが変化することに注意
  • 多用するとバグの温床になるため極力使用しない
  • サバイバルTypeScript 型アサーション
function getFirstFiveLetters(strOrNum: string | number) {
  const str = strOrNum as string;
  return str.slice(0, 5);
}

// Helloが出力
console.log(getFirstFiveLetters('Hello! World!'));

// ランタイムエラーが発生
console.log(getFirstFiveLetters(123));

as const

  • 型アサーションと構文が似ているが、型を変換する危険な機能ではない。
  • 式 as constの構文で記述。
  • 基本的にはas constが付けられた式に登場する各種リテラルを『変更できない』ものとして扱う。
  • サバイバルTypeScript as const
// 1. 配列リテラルの型推論結果を配列型ではなくreadonlyのタプル型にする
// const names: readonly ["Hiro", "Hana", "Masa"]
const names = ['Hiro', 'Hana', 'Masa'] as const;

/* 2. オブジェクトリテラルから推論されるオブジェクトのプロパティが全てreadonlyになる。
  const person: {
    readonly name: "Hiro";
    readonly age: 20;
  }
*/
const person = { name: 'Hiro', age: 20 } as const;

/* 3. 文字列・数値・Bigint・真偽値リテラルに対して
      付けられるリテラル型が広がらないリテラル型に固定される。
 */
// let Hiro1: stringと推論される。
const wideningHiro = 'Hiro';
let Hiro1 = wideningHiro;

// as const で定義したらlet Hiro2: "Hiro"と推論される。
const notWideningHiro = 'Hiro' as const;
let Hiro2 = notWideningHiro

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?