moon

moon

Build for builders on blockchain
github
twitter

TypeScript 型システムの詳細解説

ts-checker は、TypeScript を学ぶための入門から上級までのシリーズで、ts の基本知識だけでなく、Type-Challenges の詳細な問題解決も含まれています。

データ型#

基本データ型#

  • 数値型 number

    const age: number = 18
    
  • 文字列型 string

    const name: string = 'lybenson'
    
  • ブール型 boolean

    const isMale: boolean = true
    
  • 空値 void: 関数が戻り値を持たないときによく使われます

    function printHeight(height: number): void {
      console.log(height)
    }
    
  • nullundefined

  • any: 他のすべての型は any のサブタイプであり、任意の型の値を any 型の変数に代入できます

    const anyUse: any = {
      name: 'lybenson'
    }
    anyUse.name
    
  • unknown: 未知の型で、any 型と同様に、任意の型の値を unknown 型の変数に代入できます

    const unknownUse: unknown = {
      name: 'lybenson'
    }
    unknownUse.name // error: 'unknownUse' is of type 'unknown'.
    
  • never: 永遠に存在しない値の型を表します

    function error(message: string): never {
      throw new Error(message)
    }
    

その他のデータ型#

関数型#

関数型を定義する際には、引数の型と戻り値の型を提供する必要があります

const sum = (a: number, b: number): number => {
  return a + b
}

戻り値の型は省略可能で、ts は自動的に型推論を行います

配列型#

配列の型宣言には主に以下の 2 つの方法があります:

const arr1: number[] = []
const arr2: Array<number> = []

タプル型#

配列は一般に同じ型の値で構成されますが、タプルは異なる型の値を格納できます

const student: [string, number] = ['lybenson', 18]

列挙型#

キーワード enum を使用して宣言します

enum Direction {
  NORTH,
  SOUTH,
  EAST,
  WEST
}

const direction: Direction = Direction.SOUTH

列挙値は省略可能で、デフォルトで 0 から始まります

ユニオン型#

ユニオン型は、変数の値が複数の型のうちの 1 つであることを示し、またはを強調し、| 記号で接続します

type Roles = 'CEO' | 'CTO' | 'CFO'

const userRole: Roles = 'CTO'

交差型#

交差型は、変数がすべての型の属性を持つことを示し、かつを強調し、& 記号で接続します

type Student = {
  name: string
}
type Employee = {
  name: string
  salary: number
}
// UserRole は Student と Employee の属性を同時に持ちます
type UserRole = Student & Employee

const user: UserRole = {
  name: 'lybenson',
  salary: 3500
}

注意

交差される 2 つの型が同じ属性名を持つが、属性の型が異なる場合、属性の型も交差します。例えば:

type Student = {
  name: number
}
type Employee = {
  name: string
  salary: number
}
// name の型が異なるため、型も交差します
type UserRole = Student & Employee
// {
//   name: number & string
//   salary: number
// }

// エラー: 値が同時に number と string 型を持つことはありません
const user: UserRole = {
  name: 'lybenson',
  salary: 3500
}

オプショナル型#

オプショナル型は具体的な型ではなく、型の一般的な形式です。

? を使用して、変数の型や関数の引数の型を宣言する際に、特定の型を指定しますが、その変数や引数が必ずしも値を持つ必要はありません。本質的には元の型に undefined 型を結合することです

function printName(firstName: string, lastName?: string) {
  if (lastName) {
    console.log(firstName + ' ' + lastName)
  } else {
    console.log(firstName)
  }
}
// lastName はオプショナル型で、渡さなくても良い
printName('lybenson')

// カスタム型でオプショナルプロパティを定義
type Employee = {
  name: string
  salary?: number
}
const emp: Employee = {
  name: 'lybenson'
}

-? はプロパティを必須にします。

読み取り専用型#

読み取り専用型も具体的な型ではありません。

readonly を使用して、プロパティが読み取り専用であり、変更できないことを示します

// name プロパティを読み取り専用として定義
type Employee = {
  readonly name: string
  salary?: number
}

const emp: Employee = {
  name: 'lybenson',
  salary: 3500
}

emp.name = 'jack ma' // Cannot assign to 'name' because it is a read-only property.

-readonly はプロパティを変更可能にします。

カスタム型#

カスタム型は主に typeinterface を使用します。両者の違いは

  • type はユニオン型、交差型、タプル型、関数型などを定義します。通常、複雑な型の組み合わせを作成するために使用されます
  • interface は主にオブジェクト型の構造を定義するために使用されます。継承などの特性を使用できます

type#

type User = {
  name: string
  age: number
  sex?: number
}

type Status = 'draft' | 'published'

interface#

interface User {
  name: string
  age: number
  sex?: number
  getName: () => string
}

注意

interface で定義された同名の型は自動的にマージされます。例えば:

interface User {
  name: string
}

interface User {
  age: number
}

// 自動的にマージされた型は
interface User {
  name: string
  age: number
}

型変換#

as#

// any に強制変換
const distance: number = '100000' as any

as const は値を可変の変数ではなく、不変の定数として扱います

const name = 'lybenson' as const

name の型は 'lybenson' であり、string ではありません

オブジェクト型の場合:

const user = {
  name: 'lybenson',
  age: 18
} as const

as const を使用しない場合、user の型は次のように推論されます

const user: {
  name: string
  age: number
}

as const を使用した場合、user の型は次のように推論されます

const user: {
  readonly name: 'lybenson'
  readonly age: 18
}

<T>#

T は変換する必要がある型です

const distance: number = <any>'100000'

組み込み型宣言#

組み込み型は、型をより便利に定義するのに役立ちます。例えば、Omit はオブジェクトのプロパティを除外できます

interface User = {
  name: string
  age: number
  sex?: number
  salary: number
  workTime: number
}

// Student 型は User 型から salary と workTime フィールドを除外した型です
type Student = Omit<User, 'salary' | 'workTime'>

完全な内容は以下の表を参照してください

型名说明
Partial<T>T 中所有属性变为可选
Required<T>T 中所有属性变为必选
Readonly<T>T 中所有属性变为只读
Pick<T, K extends keyof T>T 中选择一组属性,选择的属性在 K
Record<K extends keyof any, T>构造一个属性名类型为 K, 属性类型为 T 的对象类型。如type obj = Record<string, any>
Exclude<T, U>从联合类型 T 中剔除包含在 U 中的类型
Extract<T, U>从联合类型 T 中提取包含在 U 中的类型
Omit<T, K extends keyof any>T 中剔除在 K 中的属性
NonNullable<T>从类型 T 中排除 nullundefined
Parameters<T extends (...args: any) => any>从函数类型 T 中提取参数类型,并返回一个由参数类型组成的元组类型
ReturnType<T extends (...args: any) => any>从函数类型 T 中提取并返回函数的返回值类型
InstanceType<T extends abstract new (...args: any) => any>从构造函数类型 T 中提取并返回构造函数实例的类型
Uppercase<S extends string>将字符串类型 S 中的所有字符转换为大写字母,并返回一个新的字符串类型
Lowercase<S extends string>将字符串类型 S 中的所有字符转换为小写字母,并返回一个新的字符串类型。
Capitalize<S extends string>将字符串类型 S 的第一个字符转换为大写字母
Uncapitalize<S extends string>将字符串类型 S 的第一个字符转换为小写字母
ThisType<T>指定方法中 this 关键字的类型
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。