ข้ามไปยังเนื้อหา

Dart สำหรับ JS/TS Developer

Dart เป็นภาษา strongly typed, sound null-safe ที่ compile ได้ทั้ง native ARM และ JavaScript ถ้ารู้ TypeScript คุณเข้าใจส่วนใหญ่แล้ว — syntax ต่างกันแต่ concept เหมือนกัน บทเรียนนี้ map feature หลักของ Dart เข้ากับ TypeScript equivalent เพื่อให้อ่าน Flutter code ได้ทันที

string | null union ของ TypeScript กลายเป็น String? ใน Dart เครื่องหมาย ? ต่อท้าย type หมายความว่า “ค่านี้อาจเป็น null” ถ้าไม่มี ? หมายความว่า non-null และ compiler บังคับที่ทุก assignment

React
// TypeScript
let name: string = 'Ava';
let maybeAge: number | null = null;
let definiteAge: number = 30;
function greet(n: string): string {
return `Hello, ${n}!`;
}
Flutter
// Dart
String name = 'Ava';
int? maybeAge = null;
int definiteAge = 30;
String greet(String n) {
return 'Hello, $n!';
}
React
// TypeScript
let counter = 0; // mutable
const MAX = 100; // runtime constant
const PI = 3.14159; // runtime constant
// 'as const' for compile-time literal
const COLORS = ['red', 'green'] as const;
Flutter
// Dart
var counter = 0; // mutable, type inferred
final max = 100; // runtime constant (set once)
const pi = 3.14159; // compile-time constant
// const list = compile-time literal
const colors = ['red', 'green'];
React
// TypeScript
class User {
readonly id: string;
name: string;
constructor(id: string, name: string) {
this.id = id;
this.name = name;
}
greet(): string {
return `Hi, I'm ${this.name}`;
}
}
const u = new User('1', 'Ava');
console.log(u.greet());
Flutter
// Dart
class User {
final String id;
String name;
User(this.id, this.name); // shorthand constructor
String greet() => 'Hi, I\'m $name';
}
final u = User('1', 'Ava');
print(u.greet());
React
// TypeScript
async function fetchUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`);
return res.json() as Promise<User>;
}
// Usage
const user = await fetchUser('42');
Flutter
// Dart
Future<User> fetchUser(String id) async {
final res = await http.get(Uri.parse('/api/users/$id'));
return User.fromJson(jsonDecode(res.body));
}
// Usage
final user = await fetchUser('42');

Future<T> คือ Promise<T> ของ Dart syntax async/await เหมือนกันทุกประการ Dart ยังมี Stream<T> สำหรับ sequence ของ async value — เทียบเท่า async generator หรือ RxJS Observable

React
// TypeScript
const nums: number[] = [1, 2, 3];
const map: Record<string, number> = { a: 1, b: 2 };
const set: Set<string> = new Set(['x', 'y']);
// spread
const more = [...nums, 4, 5];
// conditional item
const isAdmin = true;
const items = ['home', ...(isAdmin ? ['admin'] : [])];
Flutter
// Dart
List<int> nums = [1, 2, 3];
Map<String, int> map = {'a': 1, 'b': 2};
Set<String> set = {'x', 'y'};
// spread
final more = [...nums, 4, 5];
// collection-if (Dart-native syntax)
final isAdmin = true;
final items = [
'home',
if (isAdmin) 'admin',
];
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

// Pure Dart logic — same as you would write in Node/TS
List<String> buildGreetings(List<String> names, {bool formal = false}) {
  return [
    for (final name in names)
      formal ? 'Good day, $name.' : 'Hey, $name!',
  ];
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    const names = ['Ava', 'Ben', 'Cleo'];
    final greetings = buildGreetings(names, formal: false);

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: const Text('Dart for JS Devs')),
        body: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            for (final g in greetings)
              Card(
                child: Padding(
                  padding: const EdgeInsets.all(12),
                  child: Text(g, style: const TextStyle(fontSize: 16)),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
Dart equivalent ของ TypeScript `string | null` คืออะไร?
`final` และ `const` ใน Dart ต่างกันอย่างไร?
Dart equivalent ของ TypeScript `Promise<T>` คืออะไร?
Feature ใดของ Dart ที่ใส่ item ใน list literal แบบ conditional ได้โดยไม่ต้องใช้ `.filter()`?