見出し画像

【Dart/TypeScript】共通点と違い。型推論ありの静的型付け・単一継承・抽象クラス・Mixin・非同期

はじめに

FlutterとReactの両方のフレームワークを別々のプロジェクトで使っているので、プログラミング言語(DartとTypeScript)とフレームワーク(FlutterとReact)の共通点と違いについて、備忘録としてまとめておく。この記事ではプログラミング言語に関して。

DartとTypeScriptの共通点と違い

型システム:型推論ありの静的型付け・型注釈オプショナル

Dart, TypeScriptともに静的型付け言語(コンパイル時に型が決定する)だが、型注釈はオプショナルで強力な型推論が働く。

Dart:var(変数キーワード)・const・final・late(変数修飾子)

  • var:初期化後も再代入が可能。型は初期化時に右辺の式からコンパイラによって推論される

  • const:コンパイル時定数。varとは組み合わせ不可

  • final:コンパイル時ではなく実行時定数。varとは組み合わせ不可

  • late:実行時に設定される遅延初期化。変数が宣言された後で初期化が行われ、初期化が行われるまで変数は値を持たない。varと組み合わせれば初期化後の再代入が可能。

Dart

// 型推論
var number = 42; // `number`はintと推論される
number = 100;    // 再代入可能
final name = 'Alice'; // `name`はStringと推論される

// 変数修飾子
const int x = 10; // コンパイル時定数。その後再代入不可能
final int x = 10; // 実行時定数。その後再代入不可能
late int x;
void main() {
  x = 10; // 初期化が遅延されているため、実行時に初期化
  print(x); // 10
}
late var number = getNumber(); // 実行時に初期化されるが、再代入可能

int add(int a, int b) {
  return a + b;
}

TypeScript:let(変数キーワード)const・readonly(変数修飾子)

  • let:変数宣言。再代入可能。同じスコープ内での再宣言は不可能。

  • const:コンパイル時定数。再代入不可

  • readonly:実行時定数というよりは変更不可のプロパティ。主にクラスのプロパティやインターフェースのフィールドに対して使用される。Dartのfinalに近い概念だが、readonlyは変数宣言には使用されない。

  • dartのlateに直接相当する機能はない

TypeScript

// 型推論
let number = 42; // `number`は`number`型と推論される
number = 39; //再代入可能
const name = 'Alice'; // `name`は`string`型と推論される
name = 'Bob'; //エラー。再代入不可

// 変数修飾子
const PI = 3.14; // コンパイル時定数

class Example {
    readonly constantValue: number = 10; // クラスのプロパティとしてのreadonly
}
const example = new Example();
// example.constantValue = 15; // エラー: cannot assign to 'constantValue' because it is a read-only property.


// add関数のパラメータ`x`と`y`、戻り値は型推論により`any`型とされる
function add(x, y) {
  return x + y;
}

// add関数のパラメータに型注釈を追加(推奨)
function add(x: number, y: number) {
  return x + y; // 戻り値は`number`型と推論される
}

関数:引数(オプション・名前つき・必須)

Dart

  • 一般的な定義の他にオプション引数/名前つき引数/必須引数が設定できる

Dart

// オプション引数
// 引数がなくても呼び出せる(デフォルトの値が使われる)
void func1(String param1, [int param2=0]){
  print("$param1,$param2");
}
// 名前つき引数
// 名前を指定して呼び出せる
void func2({String? param1, int? param2}){
  print("$param1,$param2");
}
// 必須引数
// 必ず引数を渡すことを強制できる
void func3({required String param1, required int param2}){
  print("$param1,$param2");
}
void main() {
  func1("func1");
  func2(param1:"func2");
  func3(param1:"func3",param2:3);
}

// 出力結果
// func1,0
// func2,null
// func3,3

TypeScript

TypeScript

// オプション引数
// 引数がない場合、undefinedがデフォルト値として使われる
function func1(param1: string, param2?: number) {
  console.log(`${param1}, ${param2}`);
}

// 名前付き引数(オブジェクトを引数として使用)
// 引数の順番に関係なく、名前で指定して値を渡すことができる
function func2({param1, param2}: {param1?: string, param2?: number}) {
  console.log(`${param1}, ${param2}`);
}

// 必須引数
// 引数の前に`?`をつけないと、その引数は必須となる
function func3(param1: string, param2: number) {
  console.log(`${param1}, ${param2}`);
}

func1("func1");
func2({param1: "func2"});
func3("func3", 3);

オブジェクティブ指向:抽象クラス・Mixins

抽象クラス

  • Dartの抽象クラスはサブクラスに具体的な実装を強制する手段を提供し、TypeScriptのinterfaceはクラスに特定の構造を強制する手段を提供する。

Dart:

  • オブジェクト指向言語。インスタンスの生成:newキーワードはオプショナル

  • 単一継承:extends→Mixin(特定のメソッドやプロ…

続きは、こちらで記載しています。


よろしければサポートお願いします!いただいたサポートはクリエイターとしての活動費に使わせていただきます!