មូលដ្ឋានគ្រឹះ TypeScript
មាតិកា
- បញ្ហាដែល TypeScript ដោះស្រាយ
- ដំឡើង និងដំណើរការ Compiler
- Annotation និង Inference
- Type មូលដ្ឋាន
- Array និង Tuple
- Object Type៖ type និង interface
- Union និង Literal Type
- unknown និង any
- ការកំណត់ Type ឲ្យ Function
- ភ្លក់រស Generic
- tsconfig.json និង strict
- ការអានកំហុសរបស់ Compiler
- សាកល្បងដោយខ្លួនឯង
1. បញ្ហាដែល TypeScript ដោះស្រាយ
នៅក្នុង កំហុស និងការ Debug អ្នកបានជួប TypeError: Cannot read properties of undefined។ JavaScript រកឃើញកំហុសប្រភេទនេះតែពេលបន្ទាត់នោះដំណើរការ ហើយប្រហែលជាតែនៅលើទូរស័ព្ទរបស់អ្នកប្រើប៉ុណ្ណោះ។ JavaScript អនុញ្ញាតឲ្យអ្នកបញ្ជូន string កន្លែងដែលត្រូវការលេខ ឬវាយឈ្មោះ property ខុស ហើយមិននិយាយអ្វីទាល់តែវាខូច។
TypeScript គឺជា JavaScript ដែលមានស្រទាប់បន្ថែម៖ អ្នកពិពណ៌នា type នៃតម្លៃរបស់អ្នក ហើយឧបករណ៍មួយឈ្មោះ compiler ពិនិត្យកូដរបស់អ្នក មុន ពេលវាដំណើរការ។
function double(n: number) {
return n * 2;
}
double("5"); // កំហុសត្រូវបានរកឃើញពេលអ្នកវាយ មិនមែនពេលអ្នកប្រើចុច
ការពិតបីដែលត្រូវចងចាំ៖
- TypeScript គឺជា superset នៃ JavaScript។ JavaScript ត្រឹមត្រូវទាំងអស់ គឺជា TypeScript ត្រឹមត្រូវ ដូច្នេះអ្នកអាចរៀនវាបន្តិចម្តងៗ។
- Browser និង Node មិនអាចដំណើរការឯកសារ
.tsដោយផ្ទាល់ទេ។ Compiler បំប្លែងវាទៅជាឯកសារ.jsធម្មតា។ - Type មាន តែពេលអ្នកសរសេរ និង compile ប៉ុណ្ណោះ។ វាបាត់ពី JavaScript ចុងក្រោយ ដូច្នេះវាមិនមានតម្លៃអ្វីពេល runtime ហើយវាក៏មិនអាចការពារអ្នកពេល runtime ដែរ។ អ្នកនឹងឃើញមូលហេតុក្នុងជំពូកបន្ទាប់។
2. ដំឡើង និងដំណើរការ Compiler
TypeScript ត្រូវបានដំឡើងដោយ npm (ពី Module, Node, និង npm)។ នៅក្នុង folder គម្រោងរបស់ Dara៖
npm init -y
npm i -D typescript
npx tsc --version
-D មានន័យថា dev dependency៖ ឧបករណ៍ដែលអ្នកត្រូវការពេលសាងសង់ មិនមែនជាកូដដែល browser load ទេ។ npx ដំណើរការកម្មវិធីដែលបានដំឡើងក្នុងគម្រោង។
បង្កើត hello.ts៖
const message: string = "Hello, Dara";
console.log(message);
Compile វា៖
npx tsc hello.ts
node hello.js
ឥឡូវអ្នកមាន hello.js នៅជាប់ hello.ts ហើយ Node ដំណើរការឯកសារ JavaScript។ សម្រាប់ជំពូកដែលនៅសល់ អ្នកអាចពិនិត្យឧទាហរណ៍ដោយ npx tsc --noEmit --strict file.ts ដែលគ្រាន់តែពិនិត្យកូដ ហើយមិនសរសេរឯកសារទេ។ Editor ដូចជា VS Code ធ្វើការពិនិត្យដូចគ្នានេះពេលអ្នកវាយ ហើយបង្ហាញបន្ទាត់ក្រោមពណ៌ក្រហម។
3. Annotation និង Inference
Type annotation គឺសញ្ញាចុចពីរភ្លោះ និង type បន្ទាប់ពីឈ្មោះ៖
let title: string = "Portfolio";
ជាញឹកញាប់អ្នកមិនត្រូវការវាទេ។ TypeScript រកឃើញ type ពីតម្លៃ។ នេះហៅថា inference៖
let year = 2025; // TypeScript infer ថា៖ number
year = 2026; // ត្រឹមត្រូវ
year = "2026"; // Error: Type 'string' is not assignable to type 'number'.
ច្បាប់ជាក់ស្តែង៖
| កន្លែង | ត្រូវ annotate ឬទេ? |
|---|---|
| Variable ដែលមានតម្លៃចាប់ផ្តើមច្បាស់លាស់ | ទេ ទុកឲ្យ inference ធ្វើការ |
| Parameter របស់ function | បាទ/ចាស ជានិច្ច |
| Return type របស់ function | ស្រេចចិត្ត ប៉ុន្តែមានប្រយោជន៍សម្រាប់ function សាធារណៈ |
Variable ដែលចាប់ផ្តើមទទេ ឬជា null | បាទ/ចាស |
ដាក់ mouse លើ variable ណាក៏បានក្នុង VS Code ដើម្បីមើល type ដែល TypeScript បានជ្រើស។
4. Type មូលដ្ឋាន
ទាំងនេះត្រូវនឹងតម្លៃដែលអ្នកបានរៀនក្នុង តម្លៃ, Variable, និង Type៖
const title: string = "Portfolio";
const year: number = 2025;
const isDone: boolean = false;
const nothing: null = null;
const missing: undefined = undefined;
const big: bigint = 10n;
សូមកត់សម្គាល់ថាឈ្មោះ type សរសេរជាអក្សរតូច៖ string, number, boolean។ String និង Number ដែលសរសេរអក្សរធំ គឺជា object ចាស់ៗផ្សេងគ្នា។ កុំប្រើវាជា type។
5. Array និង Tuple
Array type គឺ type របស់ធាតុ ដែលមាន [] តាមក្រោយ៖
const tags: string[] = ["html", "css"];
const scores: Array<number> = [90, 85];
tags.push(42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'.
string[] និង Array<string> មានន័យដូចគ្នា។ មនុស្សភាគច្រើនចូលចិត្ត string[]។
Tuple គឺ array ដែលមានប្រវែងថេរ ហើយទីតាំងនីមួយៗមាន type ផ្ទាល់ខ្លួន៖
const pair: [string, number] = ["Dara", 25];
const [who, age] = pair; // who: string, age: number
ប្រើ tuple សម្រាប់ក្រុមតូចៗដែលមានទំហំថេរ។ សម្រាប់អ្វីដែលមានផ្នែកមានឈ្មោះ សូមប្រើ object។
6. Object Type៖ type និង interface
ដើម្បីពិពណ៌នា object សូមរាយ property និង type របស់វា។ នេះគឺរូបរាងនៃគម្រោងមួយរបស់ Dara៖
type Project = {
title: string;
year: number;
url?: string; // សញ្ញា ? ធ្វើឲ្យវាជាជម្រើស
};
const p: Project = { title: "Quiz App", year: 2025 };
? មានន័យថា property អាចបាត់។ Type របស់វាក្លាយជា string | undefined ដូច្នេះ TypeScript នឹងបង្ខំឲ្យអ្នកដោះស្រាយករណីបាត់មុនពេលប្រើ៖
p.url.toUpperCase(); // Error: 'p.url' is possibly 'undefined'.
p.url?.toUpperCase(); // ត្រឹមត្រូវ៖ optional chaining
មានវិធីទីពីរក្នុងការដាក់ឈ្មោះរូបរាង object គឺ interface៖
interface Person {
name: string;
age: number;
}
interface Student extends Person {
school: string;
}
type | interface | |
|---|---|---|
| រូបរាង Object | បាទ/ចាស | បាទ/ចាស |
| Union, tuple, alias សាមញ្ញ | បាទ/ចាស | ទេ |
| ការពង្រីក | & (intersection) | extends |
សម្រាប់ការងារប្រចាំថ្ងៃ ពួកវាស្ទើរតែដូចគ្នា។ ជម្រើសសាមញ្ញ៖ ប្រើ type គ្រប់ទីកន្លែង ហើយប្រើ interface ប្រសិនបើក្រុម ឬ library ប្រើរួចហើយ។ ស៊េរីនេះប្រើ type។
7. Union និង Literal Type
Union មានន័យថា "មួយក្នុងចំណោម type ទាំងនេះ" សរសេរដោយ |៖
type ID = string | number;
function format(value: ID): string {
return `ID: ${value}`;
}
Literal type គឺ type ដែលអនុញ្ញាតតែតម្លៃមួយប៉ុណ្ណោះ ដូចជា "css"។ បញ្ចូល literal ក្នុង union ហើយអ្នកនឹងបានបញ្ជីតម្លៃដែលអនុញ្ញាតយ៉ាងច្បាស់លាស់៖
type Tag = "html" | "css" | "javascript";
let tag: Tag = "css";
tag = "js"; // Error: Type '"js"' is not assignable to type 'Tag'.
នេះគឺជាលក្ខណៈពិសេសមួយក្នុងចំណោមលក្ខណៈដែលមានប្រយោជន៍បំផុតសម្រាប់អ្នកចាប់ផ្តើម។ ការវាយខុសដូចជា "js" ត្រូវបានចាប់បានភ្លាមៗ ហើយ editor របស់អ្នកស្នើតម្លៃត្រឹមត្រូវទាំងបីពេលអ្នកវាយ។
8. unknown និង any
ពេលខ្លះអ្នកមិនដឹង type របស់តម្លៃ ឧទាហរណ៍ទិន្នន័យពី JSON.parse។ TypeScript មានពីរវិធីដើម្បីនិយាយបែបនេះ៖
let anything: any = "hi";
anything.foo.bar; // TypeScript មិនប្រាប់កំហុស ប៉ុន្តែគាំងពេលដំណើរការ
let safe: unknown = "hi";
safe.toUpperCase(); // Error: 'safe' is of type 'unknown'.
if (typeof safe === "string") {
console.log(safe.toUpperCase()); // ត្រឹមត្រូវ៖ បានពិនិត្យមុន
}
any | unknown | |
|---|---|---|
| អត្ថន័យ | "បិទ type checker" | "ខ្ញុំមិនទាន់ដឹងទេ ដូច្នេះត្រូវពិនិត្យមុន" |
| អាចប្រើដោយផ្ទាល់ឬទេ? | បាទ/ចាស ដោយគ្មានការពិនិត្យ | ទេ អ្នកត្រូវពិនិត្យ type របស់វា |
| សុវត្ថិភាព? | ទេ | បាទ/ចាស |
ចៀសវាង any។ វាលាក់ bug ដែល TypeScript ត្រូវបានបង្កើតឡើងដើម្បីចាប់។ ពេល type មិនស្គាល់ពិតប្រាកដ សូមប្រើ unknown ហើយ narrow វា (ជំពូកបន្ទាប់)។
9. ការកំណត់ Type ឲ្យ Function
Annotate parameter ហើយប្រសិនបើចង់ ក៏ annotate តម្លៃ return ដែរ៖
function add(a: number, b: number): number {
return a + b;
}
const double = (n: number): number => n * 2;
add(1); // Error: Expected 2 arguments, but got 1.
add("1", 2); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.
Parameter ស្រេចចិត្តប្រើ ? ហើយតម្លៃលំនាំដើមដំណើរការដូចធម្មតា៖
function greet(name: string, greeting = "Hello", suffix?: string): string {
return `${greeting}, ${name}${suffix ?? ""}`;
}
Function ដែលមិនត្រឡប់អ្វីមាន return type ជា void។ អ្នកក៏អាចសរសេរ type របស់តម្លៃ function ដូចជា callback ផងដែរ៖
let callback: (message: string) => void;
callback = (m) => console.log(m); // m ត្រូវបាន infer ជា string
សូមអាន (message: string) => void ថា "function ដែលទទួល string ហើយមិនត្រឡប់អ្វី"។
10. ភ្លក់រស Generic
អ្នកបានប្រើ generic type រួចហើយ៖ Array<number>។ ផ្នែកក្នុងដង្កៀបមុតគឺ type parameter ជា placeholder ដែលត្រូវបំពេញនៅពេលក្រោយ។ នេះគឺជា function ដែលដំណើរការសម្រាប់ array គ្រប់ប្រភេទ៖
function first<T>(items: T[]): T | undefined {
return items[0];
}
const a = first([1, 2, 3]); // a: number | undefined
const b = first(["x", "y"]); // b: string | undefined
T តំណាងឲ្យ "type ណាក៏ដោយដែល array ផ្ទុក"។ TypeScript infer វាពី argument ដូច្នេះអ្នកកម្រសរសេរ <number> ដោយខ្លួនឯង។ អ្នកនឹង ប្រើ generic ពី library (Promise<string>, Array<Project>) ច្រើនជាងសរសេរវាដោយខ្លួនឯង។
11. tsconfig.json និង strict
ជំនួសឲ្យជម្រើស command-line រាល់ពេល ឯកសារ tsconfig.json នៅ root នៃគម្រោងផ្ទុកការកំណត់។ បង្កើតមួយ៖
npx tsc --init
ឯកសារដែលបង្កើតមានជម្រើសច្រើនដែលត្រូវបាន comment។ កំណែតូច និងស្អាតមើលទៅដូចនេះ៖
{
"compilerOptions": {
"target": "ES2023",
"module": "ES2022",
"moduleResolution": "bundler",
"strict": true,
"rootDir": "src",
"outDir": "dist"
},
"include": ["src"]
}
| ជម្រើស | អត្ថន័យ |
|---|---|
target | កំណែ JavaScript ណាដែលត្រូវបង្កើត |
module | ប្រើ import/export ក្នុងលទ្ធផល |
strict | បើកការពិនិត្យតឹងរ៉ឹងបំផុតទាំងអស់ |
rootDir / outDir | អានពី src/ សរសេរទៅ dist/ |
include | ឯកសារណាដែលត្រូវ compile |
រក្សា "strict": true ជានិច្ច។ វាធ្វើឲ្យ TypeScript ត្អូញត្អែរអំពី any ដោយបង្កប់ និងអំពី null/undefined កន្លែងដែលមិនរំពឹងទុក។ ដំបូងវាមើលទៅតឹងរ៉ឹង ប៉ុន្តែទាំងនោះគឺជាកំហុសដែលបង្កឲ្យមាន bug ពិតប្រាកដ។ ពេលមាន tsconfig.json គ្រាន់តែដំណើរការ npx tsc ហើយវាប្រើការកំណត់។
12. ការអានកំហុសរបស់ Compiler
កំហុសរបស់ compiler មើលទៅវែង ប៉ុន្តែវាមានលំនាំ។ នេះគឺជាឯកសារដែលមានកំហុសច្រើន៖
let year = 2025;
year = "2026";
const p = { title: "x", year: 1 };
p.titel;
function f(x) { return x; }
const el = null;
el.foo;
ការដំណើរការ npx tsc --noEmit បោះពុម្ព៖
bad.ts(2,1): error TS2322: Type 'string' is not assignable to type 'number'.
bad.ts(5,3): error TS2551: Property 'titel' does not exist on type '{ title: string; year: number; }'. Did you mean 'title'?
bad.ts(7,12): error TS7006: Parameter 'x' implicitly has an 'any' type.
bad.ts(10,1): error TS18047: 'el' is possibly 'null'.
ពន្យល់មួយឲ្យលម្អិត៖
bad.ts(5,3): error TS2551: Property 'titel' does not exist ...
└─┬──┘└─┬─┘ └──┬──┘ └──────────────┬─────────────────
file line,column code message
- អាន សារ មុន។ វាបញ្ជាក់តម្លៃ និងបញ្ហា។
- សារដូចជា "X is not assignable to Y" មានន័យថា "អ្នកបានឲ្យ X ដល់ខ្ញុំ កន្លែងដែលត្រូវការ Y"។
- រកមើលការស្នើដូចជា Did you mean 'title'?
- សម្រាប់កំហុសវែងៗ សូមអានបន្ទាត់ ដំបូង និង ចុងក្រោយ៖ ផ្នែកកណ្តាលភាគច្រើនគ្រាន់តែនិយាយលម្អិតម្តងទៀត។
- កូដកំហុស (ដូចជា
TS2322) មានប្រយោជន៍សម្រាប់ស្វែងរកលើ web។
កែកំហុសពីលើចុះក្រោម៖ កំហុសដំបូងមួយតែងបង្កឲ្យមានកំហុសជាច្រើនតាមក្រោយ។
13. សាកល្បងដោយខ្លួនឯង
- ដំឡើង និង compile។ នៅក្នុង folder ទទេ ដំណើរការ
npm init -yនិងnpm i -D typescript។ សរសេរhello.tscompile វាដោយnpx tscហើយដំណើរការលទ្ធផលដោយnode។ - Inference ឬ annotation? សរសេរ
let count = 0;ហើយដាក់ mouse លើវា។ បន្ទាប់មកសាកល្បងcount = "one"ហើយអានកំហុស។ - ពិពណ៌នាគម្រោង។ សរសេរ type
Projectដែលមានtitle,yearនិងurlស្រេចចិត្ត។ បង្កើតគម្រោងពីរ មួយមាន URL និងមួយគ្មាន ហើយបោះពុម្ពurl?.lengthសម្រាប់ទាំងពីរ។ - កំណត់តម្លៃ។ បង្កើត
type Tag = "html" | "css" | "javascript"និង functiondescribeTag(tag: Tag): string។ សាកល្បងហៅវាជាមួយ"python"ហើយអានកំហុស។ - Generic function។ សរសេរ
last<T>(items: T[]): T | undefined។ ហៅវាជាមួយលេខ និងជាមួយ string ហើយដាក់ mouse លើលទ្ធផលនីមួយៗ។ - បើកការពិនិត្យ។ បង្កើត
tsconfig.jsonជាមួយ"strict": true។ សរសេរ function ដែលមាន parameter គ្មាន type ហើយកែកំហុសដែលវារាយការណ៍។
ឥឡូវអ្នកដឹង TypeScript គ្រប់គ្រាន់ដើម្បីប្រើវាលើគម្រោងពិតប្រាកដ។ នៅក្នុងជំពូកចុងក្រោយ យើងបំប្លែងទំព័ររបស់ Dara ហើយមើលកន្លែងដែល type ជួយ និងកន្លែងដែលវាឈប់៖ TypeScript ក្នុងការអនុវត្តជាក់ស្តែង។
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!