方言を話すおしゃべり猫型ロボット『ミーア』をリリースしました(こちらをクリック)

[Dart/TypeScript] Similarities and Differences. Static typing with type inference, single inheritance, abstract classes, Mixin, asynchronous

dart-typescript-similarities-and-differences
This article can be read in about 15 minutes.

Introduction.

Since we are using both Flutter and React frameworks in separate projects, this is a reminder about the similarities and differences between the programming languages (Dart and TypeScript) and frameworks (Flutter and React). In this article, regarding programming languages.

Similarities and differences between Dart and TypeScript

Introduction to Dart
A brief introduction to Dart programs and important concepts.
Documentation - TypeScript for the New Programmer
Learn TypeScript from scratch

Type system: static typing with type inference and type annotation optional

Both Dart and TypeScript are statically typed languages (types are determined at compile time), but type annotation is optional and powerful type inference works.

Dart: var (variable keyword), const, final, late (variable modifier)

Variables
Learn about variables in Dart.
  • var: Can be reassigned after initialization. Type is deduced by the compiler from the right-hand side expression at initialization.
  • const: Compile-time constant; cannot be combined with var
  • final: Runtime constant, not compile-time constant; cannot be combined with var
  • late: Delayed initialization set at runtime. Initialization occurs after the variable is declared, and the variable has no value until initialization occurs; when combined with var, reassignment after initialization is possible.
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 (variable keyword) const, read-only (variable modifier)

  • let Variable declaration. It can be reassigned. It cannot be redeclared in the same scope.
  • const: Compile-time constant. It cannot be reassigned.
  • read-only: A property that cannot be changed rather than a runtime constant. Used primarily for class properties and interface fields; similar in concept toDart’sfinal, butreadonly isnot used for variable declarations.
  • There is no direct equivalent to Dart’s 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`型と推論される
}

Function: Arguments (optional, named, required)

Dart.

  • Optional/named/required arguments can be set in addition to the general definition
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);

Object-oriented: Abstract Classes, Mixins

abstract class

  • Dart’s abstract class provides a means of enforcing a concrete implementation on subclasses, and TypeScript’s interface provides a means of enforcing a specific structure on classes.

Dart:.

  • Object-oriented language. Instance creation: new keyword is optional
  • Single inheritance: covered by extends→Mixin (sharing specific methods and properties among multiple classes)
  • If you start with ___, the scope becomes private.
  • static: Become a field/method belonging to the class
  • Access fields with setter/getter.
  • Abstract class: abstract, creating a non-instantiable class for use by inheritance.
Dart
abstract class Shape { // 抽象クラス定義
  void draw(); // 抽象メソッド
  void move() {
    print('Moving a shape');
  } // 具体的なメソッド実装
}

class Circle extends Shape { // サブクラス定義
  void draw() {
    print('Drawing a circle');
  } // 抽象メソッドの具体的な実装
}

void main() {
  var circle = Circle();
	var circle = new Circle(); //newキーワードは使っても使わなくても良い。上記と同じ
	var shape = Shape();  // エラー: 抽象クラスのインスタンスを生成しようとしている
  circle.draw(); // "Drawing a circle" を出力
  circle.move(); // "Moving a shape" を出力

Mixins

  • Functionality for reusing class code in multiple class hierarchies
  • mixin is defined using the mixin keyword instead of the class keyword.
  • mixin is intended to be “mixed in” with other classes using the with keyword and cannot be instantiated alone.
  • Mixed-in classes have access to the methods and properties provided by mixin.
Dart
mixin Painter {
  void paint() {
    print('Painting...');
  }
}

mixin Writer {
  void write() {
    print('Writing...');
  }
}

class Artist with Painter, Writer {}

void main() {
  final artist = Artist();
  artist.paint();  // "Painting..." を出力
  artist.write();  // "Writing..." を出力
}

TypeScript:

  • Covered by single inheritance -> interface. interface: can define object shape (properties and method signatures), but cannot contain concrete implementations of methods (abstract classes can). Cannot be instantiated directly (same as abstract classes).
TypeScript
interface Shape {
  draw(): void; // メソッドのシグネチャ
  move(): void; // メソッドのシグネチャ
}

class Circle implements Shape {
  draw() {
    console.log('Drawing a circle');
  } // インターフェイスで定義されたメソッドの実装

  move() {
    console.log('Moving a circle');
  } // インターフェイスで定義されたメソッドの実装
}

let circle = new Circle();
circle.draw(); // "Drawing a circle" を出力
circle.move(); // "Moving a circle" を出力
  • Explicitly control the visibility of members using the access modifiers private, public, and protected.
TypeScript
class Student {
  fullName: string;
  constructor(
    public firstName: string,
    public middleInitial: string,
    public lastName: string
  ) {
    this.fullName = firstName + " " + middleInitial + " " + lastName;
  }
  getFullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
}

interface Person {
  firstName: string;
  lastName: string;
  getFullName(): string;
}

function greeter(person: Person) {
  return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.textContent = greeter(user);

Asynchronous: Future (Dart), Promise (TypeScript)

Dart.

  • Asynchronous programming using Future andasync/await
  • Future is an object that may return a value at some point in the future
Dart
Future fetchUserData() {
  // 擬似的にユーザーデータの取得を非同期で行う例
  return Future.delayed(Duration(seconds: 2), () {
    return 'User data';
  });
}

void main() async {
  print('Fetching user data...');
  String userData = await fetchUserData();
  print(userData); // 2秒後に'User data'が出力される
}

TypeScript

  • Asynchronous programming with Promise andasync/await (same as JavaScript)
  • Promise is an object representing a future value
TypeScript
function fetchUserData(): Promise {
  // 擬似的にユーザーデータの取得を非同期で行う例
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('User data');
    }, 2000);
  });
}

async function main() {
  console.log('Fetching user data...');
  const userData = await fetchUserData();
  console.log(userData); // 2秒後に'User data'が出力される
}

main();

コメント

Copied title and URL