ããã«ã¡ã¯äœæ°ïŒDan Vanderkamã®æ¬ã¯ãJavaScriptãšTypeScriptã®çµéšããã§ã«ããäººã«æã圹ç«ã¡ãŸãããã®æ¬ã®ç®çã¯ãããŒã«ã䜿çšããããã«èªè
ãæè²ããããšã§ã¯ãªãã圌ãã圌ãã®ããæèãåäžãããã®ãå©ããããšã§ãããããèªãã åŸãTypeScriptã³ã³ããŒãã³ããã©ã®ããã«æ©èœããããããããçè§£ããå€ãã®èœãšã穎ãèœãšã穎ãé¿ããã¹ãã«ã䌞ã°ãããšãã§ããŸãããªãã¡ã¬ã³ã¹ã¬ã€ãã§ã¯ãåãã¿ã¹ã¯ãå®è¡ããããã«èšèªã䜿çšãã5ã€ã®ç°ãªãæ¹æ³ã瀺ããŠããŸãããã广çãªãæ¬ã§ã¯ãã©ã¡ããåªããŠãããããããŠãã®çç±ã説æããŠããŸãã
æ¬ã®æ§é
ãã®æ¬ã¯çããšãã»ã€ïŒã«ãŒã«ïŒã®ã³ã¬ã¯ã·ã§ã³ã§ããã«ãŒã«ã¯ããŒãå¥ã®ã»ã¯ã·ã§ã³ïŒç« ïŒã«ã°ã«ãŒãåãããŠãããé¢å¿ã®ãã質åã«å¿ããŠèªåŸçã«ã¢ã¯ã»ã¹ã§ããŸãã
åã«ãŒã«ã®èŠåºãã«ã¯ãã³ããå«ãŸããŠããã®ã§ãç®æ¬¡ã確èªããŠãã ãããããšãã°ãããã¥ã¡ã³ããäœæããŠããŠãã¿ã€ãæ å ±ãäœæãããã©ããçåãããå Žåã¯ãç®æ¬¡ãšã«ãŒã«30ïŒãããã¥ã¡ã³ãã§ã¿ã€ãæ å ±ãç¹°ãè¿ããªãã§ãã ãããïŒãåç §ããŠãã ããã
ãã®æ¬ã®ã»ãšãã©ãã¹ãŠã®çµè«ã¯ãã³ãŒãäŸã䜿çšããŠç€ºãããŠããŸããç§ã®ããã«ãããªãã¯äŸãèŠãŠãããã¹ãéšåã ããééããããšã«ãã£ãŠæè¡çãªæ¬ãèªãåŸåããããšæããŸãããã¡ããã説æãããèªãã§ããã ããããšæããŸãããäŸã§ã¯èŠç¹ã説æããŸããã
åãã³ããèªããšãTypeScriptããã广çã«äœ¿çšããã®ã«åœ¹ç«ã€æ¹æ³ãšçç±ãæ£ç¢ºã«çè§£ã§ããŸãããŸããäœããã®æ¹æ³ã§äœ¿çšã§ããªãããšã倿ãããã©ãããçè§£ã§ããŸãã广çãªC ++ã®äœè ã§ããã¹ã³ãããã€ã€ãŒãºã®äŸãèŠããŠããŸããããµã€ã«ãœãããŠã§ã¢éçºè ã¯ãããµã€ã«ãã¿ãŒã²ããã«åœãã£ããšãã«ããã°ã©ã ãç Žå£ãããããããªãœãŒã¹ãªãŒã¯ãé²ãããã®ã¢ããã€ã¹ãæ ã£ãå¯èœæ§ããããŸããJavaScriptã§æžãããå¶åŸ¡ã·ã¹ãã ãåãããã±ããã®ååšãç§ã¯ç¥ããŸãããããã®ãããªãœãããŠã§ã¢ã¯ãžã§ãŒã ãºãŠã§ããæé é¡ã«ãããŸããã®ã§æ³šæããŠãã ããã
åã«ãŒã«ã¯ãMustRememberããããã¯ã§çµãããŸããããããã£ãšèŠãŠã¿ããšãææã®äžè¬çãªã¢ã€ãã¢ãååŸããäž»èŠãªãã®ã匷調ããããšãã§ããŸãããã ããã«ãŒã«å šäœãèªãããšã匷ããå§ãããŸãã
æç²ãã«ãŒã«4.æ§é ã¿ã€ãã³ã°ã«æ £ãã
JavaScriptã¯æå³ããã«ããã¯ã¿ã€ãã«ãªã£ãŠããŸããæ£ããããããã£ãæã€å€ã颿°ã«æž¡ããŠãããã®å€ãã©ã®ããã«ååŸãããã¯é¢ä¿ãããŸããã圌女ã¯ããã䜿ãã ãã§ããTypeScriptã¯ãã®åäœãã¢ãã«åããŸãããæ€èšŒè ã®åã®çè§£ã¯ããªãã®çè§£ãããåºãå¯èœæ§ããããããäºæããªãçµæãçããããšããããŸããæ§é åã¿ã€ãã³ã°ã®ã¹ãã«ã身ã«ä»ããããšã§ãå®éã«ãšã©ãŒãçºçããŠããå Žæãããæ£ç¢ºã«ææ¡ããããä¿¡é Œæ§ã®é«ãã³ãŒããäœæã§ããããã«ãªããŸãã
ããšãã°ãç©çã©ã€ãã©ãªã䜿çšããŠããŠã2Dãã¯ãã«ã¿ã€ãããããšããŸãã
interface Vector2D {
x: number;
y: number;
}
ãã®é·ããèšç®ãã颿°ãèšè¿°ããŸãã
function calculateLength(v: Vector2D) {
return Math.sqrt(v.x * v.x + v.y * v.y);
}
ååä»ããã¯ãã«ã®å®çŸ©ãå ¥åããŸãã
interface NamedVector {
name: string;
x: number;
y: number;
}
calculateLength颿°ã¯ãæ°å€ã§ããxããããã£ãšyããããã£ãå«ãŸããŠãããããNamedVectorã§æ©èœããŸããTypeScriptã¯ãããçè§£ããŸãïŒ
const v: NamedVector = { x: 3, y: 4, name: 'Zee' };
calculateLength(v); // ok, 5.
è峿·±ãã®ã¯ãVector2DãšNamedVectorã®é¢ä¿ã宣èšããªãã£ãããšã§ãããŸããNamedVectorã®ä»£æ¿ã®calculateLengthå®è¡ãèšè¿°ããå¿ èŠããããŸããã§ãããTypeScriptã¿ã€ãã·ã¹ãã ã¯ãJavaScriptã®å®è¡æã®åäœïŒã«ãŒã«1ïŒãã·ãã¥ã¬ãŒãããŸããããã«ãããNamedVectorã¯ãVector2Dã«å¹æµããæ§é ã«åºã¥ããŠcalculateLengthãåŒã³åºãããšãã§ããŸãããããã£ãŠããæ§é ã¿ã€ãã³ã°ããšãã衚çŸã
ããããããã¯åé¡ãåŒãèµ·ããå¯èœæ§ããããŸãã3Dãã¯ãã«ã¿ã€ãã远å ãããšããŸãã
interface Vector3D {
x: number;
y: number;
z: number;
}
ãã¯ãã«ãæ£èŠåãã颿°ãèšè¿°ããŸãïŒé·ãã1ã«çããããŸãïŒã
function normalize(v: Vector3D) {
const length = calculateLength(v);
return {
x: v.x / length,
y: v.y / length,
z: v.z / length,
};
}
ãã®é¢æ°ãåŒã³åºããšãã»ãšãã©ã®å Žåãè€æ°ã®é·ããåŸãããŸãã
> normalize({x: 3, y: 4, z: 5})
{ x: 0.6, y: 0.8, z: 1 }
äœãããŸãããããTypeScriptããã°ãå ±åããªãã£ãã®ã¯ãªãã§ããïŒ
ãã°ã¯ãcalculateLengthã2Dãã¯ãã«ã§æ©èœããã®ã«å¯Ÿããnormalizeã¯3Dã§æ©èœããããšã§ãããããã£ãŠãæ£èŠåäžã«zã³ã³ããŒãã³ãã¯ç¡èŠãããŸãã
ã¿ã€ããã§ãã«ãŒãããããã£ããããªãã£ãã®ã¯å¥åŠã«æãããããããŸãããã¿ã€ãã2Dãã¯ãã«ã§æ©èœããã®ã«ããªã3Dãã¯ãã«ã§calculateLengthãåŒã³åºãããšãèš±å¯ãããŠããã®ã§ããïŒ
ååä»ãã§ããŸãæ©èœãããã®ã¯ããã§è£ç®ã«åºãŸããã {xãyãz}ãªããžã§ã¯ãã§calculateLengthãåŒã³åºããŠãããšã©ãŒã¯ã¹ããŒãããŸããããããã£ãŠãåãã§ãã¯ã¢ãžã¥ãŒã«ã¯æå¥ãèšãããæçµçã«ãã°ãçºçããŸãããã®å Žåã«ãšã©ãŒãæ€åºãããå Žåã¯ãã«ãŒã«37ãåç §ããŠãã ããã
颿°ãäœæãããšãã宣èšããããããã£ã«ãã£ãŠåŒã³åºãããããšã¯å®¹æã«æ³åã§ããŸããããã以å€ã¯äœããããŸãããããã¯ãå°å°ãããããŸãã¯ãæ£ç¢ºãªãã¿ã€ããšåŒã°ããTypeScriptã¿ã€ãã®ã·ã¹ãã ã«ã¯é©çšã§ããŸããã奜ããšå¥œãŸãããšã«ããããããã¿ã€ãã¯ããã§éãããŠããŸãã
æã ããã¯é©ãã«ã€ãªãããŸãïŒ
function calculateLengthL1(v: Vector3D) {
let length = 0;
for (const axis of Object.keys(v)) {
const coord = v[axis];
// ~~~~~~~ "any",
// "string"
// "Vector3D"
length += Math.abs(coord);
}
return length;
}
ãªããããééããªã®ã§ããïŒaxisã¯Vector3Dã®vããŒã®1ã€ã§ãããããxãyããŸãã¯zã§ããå¿ èŠããããŸãããããŠãå ã®Vector3D宣èšã«ããã°ããããã¯ãã¹ãŠæ°åã§ãããããã£ãŠã座æšã¿ã€ããæ°å€ã«ãã¹ãã§ã¯ãããŸãããïŒ
ããã¯èª€ã£ããšã©ãŒã§ã¯ãããŸãããVector3Dã¯å³å¯ã«å®çŸ©ãããŠãããä»ã®ããããã£ã¯ãããŸããã圌ã¯ã§ãããïŒ
const vec3D = {x: 3, y: 4, z: 1, address: '123 Broadway'};
calculateLengthL1(vec3D); // ok, NaN
vã¯ããããä»»æã®ããããã£ãæã€å¯èœæ§ããããããaxisã®ã¿ã€ãã¯stringã§ããTypeScriptãv [axis]ãåãªãæ°å€ãšèããçç±ã¯ãããŸããããªããžã§ã¯ããå埩åŠçããå Žåãæ£ããå ¥åãè¡ãã®ãé£ããå ŽåããããŸããã«ãŒã«54ã§ãã®ãããã¯ã«æ»ããŸãããä»ã®ãšããã«ãŒãã¯äœ¿çšããŸããã
function calculateLengthL1(v: Vector3D) {
return Math.abs(v.x) + Math.abs(v.y) + Math.abs(v.z);
}
æ§é åã¯ãå¯èœãªããããã£å²ãåœãŠã«ã€ããŠæ¯èŒãããã¯ã©ã¹ã§é©ããåŒãèµ·ããå¯èœæ§ããããŸãã
class C {
foo: string;
constructor(foo: string) {
this.foo = foo;
}
}
const c = new C('instance of C');
const d: C = { foo: 'object literal' }; // ok!
ãªãdãCã«å²ãåœãŠãããšãã§ããã®ã§ããïŒæååã§ããããããã£fooããããŸãããŸããåŒæ°ã䜿çšããŠåŒã³åºãããšãã§ããïŒObject.prototypeããã®ïŒã³ã³ã¹ãã©ã¯ã¿ãŒããããŸãïŒéåžžã¯åŒæ°ãªãã§åŒã³åºãããŸãïŒããããã£ãŠãæ§é ã¯åãã§ããããã¯ãCã³ã³ã¹ãã©ã¯ã¿ãŒã«ããžãã¯ãããããããåŒã³åºã颿°ãäœæããå Žåãé©ãã«ã€ãªããå¯èœæ§ããããŸããããã¯ãCã¿ã€ããã©ã¡ãŒã¿ã®å®£èšã«ãã£ãŠCãŸãã¯ãã®ãµãã¯ã©ã¹ã«å±ããããšãä¿èšŒãããC ++ãJavaãªã©ã®èšèªãšã®å€§ããªéãã§ãã
æ§é åã¯ããã¹ããäœæãããšãã«éåžžã«åœ¹ç«ã¡ãŸããããŒã¿ããŒã¹ã¯ãšãªãå®è¡ããŠçµæãåŠçãã颿°ããããšããŸãã
interface Author {
first: string;
last: string;
}
function getAuthors(database: PostgresDB): Author[] {
const authorRows = database.runQuery(`SELECT FIRST, LAST FROM
AUTHORS`);
return authorRows.map(row => ({first: row[0], last: row[1]}));
}
ããããã¹ãããããã«ãPostgresDBã¢ãã¯ãäœæããããšãã§ããŸãããã ããããè¯ã解決çã¯ãæ§é åãããåæå®ã䜿çšããããçãã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ããããšã§ãã
interface DB {
runQuery: (sql: string) => any[];
}
function getAuthors(database: DB): Author[] {
const authorRows = database.runQuery(`SELECT FIRST, LAST FROM
AUTHORS`);
return authorRows.map(row => ({first: row[0], last: row[1]}));
}
runQueryã¡ãœããããããããpostgresDBãåºåã®getAuthors颿°ã«æž¡ãããšãã§ããŸããæ§é åå ¥åã§ã¯ãPostgresDBãDBãå®è¡ããŠããããšãå ±åããå¿ èŠã¯ãããŸãããTypeScriptããããçè§£ããŸãã
ãã¹ããäœæãããšãã«ãããåçŽãªãªããžã§ã¯ããæž¡ãããšãã§ããŸãã
test('getAuthors', () => {
const authors = getAuthors({
runQuery(sql: string) {
return [['Toni', 'Morrison'], ['Maya', 'Angelou']];
}
});
expect(authors).toEqual([
{first: 'Toni', last: 'Morrison'},
{first: 'Maya', last: 'Angelou'}
]);
});
TypeScriptã¯ããã¹ãDBãã€ã³ã¿ãŒãã§ã€ã¹ã«æºæ ããŠããããšã確èªããŸããåæã«ããã¹ãã«ã¯åºåããŒã¿ããŒã¹ã«é¢ããæ å ±ã¯ãŸã£ããå¿ èŠãããŸãããã¢ãã¯ã©ã€ãã©ãªã¯å¿ èŠãããŸãããæœè±¡åïŒDBïŒãå°å ¥ããããšã«ãããå®è¡ã®è©³çްïŒPostgresDBïŒããããžãã¯ãè§£æŸããŸããã
æ§é åã®ãã1ã€ã®å©ç¹ã¯ãã©ã€ãã©ãªéã®äŸåé¢ä¿ãæç¢ºã«å£ãããšãã§ããããšã§ãããã®ãããã¯ã®è©³çްã«ã€ããŠã¯ãã«ãŒã«51ãåç §ããŠãã ããã
JavaScriptã¯ããã¯ã¿ã€ãã³ã°ã䜿çšããTypeScriptã¯æ§é åã¿ã€ãã³ã°ã䜿çšããŠã¢ãã«åããããšãèŠããŠãããŠãã ããããã®çµæãã€ã³ã¿ãŒãã§ãŒã¹ã«å²ãåœãŠãããå€ã«ã¯ã宣èšãããã¿ã€ãã§æå®ãããŠããªãããããã£ãå«ãŸããå ŽåããããŸããTypeScriptã®ã¿ã€ãã¯å°å°ãããŠããŸããã
ã¯ã©ã¹ãæ§é çãªåæå®èŠåã«åŸãããšã«æ³šæããŠãã ããããããã£ãŠãäºæ³ãšã¯ç°ãªãã¯ã©ã¹ãµã³ãã«ã«ãªã£ãŠããŸãå¯èœæ§ããããŸãã
æ§é ååã䜿çšããŠãã¢ã€ãã ã®ãã¹ãã容æã«ããŸãã
ã«ãŒã«5.ã¿ã€ãã®äœ¿çšãå¶éãã
TypeScriptã®ã¿ã€ãã·ã¹ãã ã¯æ®µéçã§éžæçã§ããæŒžé²æ§ã¯ãã³ãŒãã«ã¿ã€ããæ®µéçã«è¿œå ããæ©èœãšãå¿ èŠãªãšãã«ã¿ã€ããã§ãã¯ã¢ãžã¥ãŒã«ãç¡å¹ã«ããæ©èœã®éžææ§ã«çŸããŸãããã®å Žåã«å¶åŸ¡ããããŒã¯ãä»»æã®ã¿ã€ãã§ãã
let age: number;
age = '12';
// ~~~ '"12"' 'number'.
age = '12' as any; // ok
ãšã©ãŒã瀺ããšã³ã¿ã€ãã«ã¡ã³ãã¢ãžã¥ãŒã«ã§ããã远å ããã ãã§åé¿ã§ããŸãã TypeScriptã®äœ¿çšãéå§ãããšãããšã©ãŒãçè§£ããŠããªãå Žåãæ€èšŒããŒã«ãä¿¡é ŒããŠããªãå ŽåããŸãã¯ã¿ã€ãã®èª¬æã«æéããããããªãå Žåã¯ãä»»æã®ã¿ã€ããŸãã¯ã¢ãµãŒã·ã§ã³ãšããŠäœ¿çšããããªãããšããããŸãããã ããTypeScriptã®å©ç¹ã®å€ããç¡å¹ã«ãªãããšãå¿ããªãã§ãã ãããã€ãŸãã
ã³ãŒãã®å®å šæ§ãäœäžããŸãã
äžèšã®äŸã§ã¯ã宣èšãããã¿ã€ãã«å¿ããŠãå¹Žéœ¢ã¯æ°å€ã§ããããããã©ã®æååãããã«å²ãåœãŠãããšãã§ããŸãããæ€èšŒè ã¯ããããïŒå®£èšããæ¹æ³ã§ããïŒæ°å€ã§ãããšæ³å®ããæ··ä¹±ãæããŸãã
age += 1; // ok. age "121".
æ¡ä»¶ã«éåããããšãã§ããŸã
颿°ãäœæãããšãã«ãåŒã³åºãããç¹å®ã®ããŒã¿ã¿ã€ããåä¿¡ãããšãåºåã«å¯Ÿå¿ããã¿ã€ããçæãããšããæ¡ä»¶ãèšå®ããŸããããã¯ã次ã®ããã«éåããŸãã
function calculateAge(birthDate: Date): number {
// ...
}
let birthDate: any = '1990-01-19';
calculateAge(birthDate); // ok
birthDateãã©ã¡ãŒã¿ãŒã¯ãæååã§ã¯ãªãæ¥ä»ã§ããå¿ èŠããããŸããä»»æã®ã¿ã€ãã«ãããcalculateAgeã«é¢é£ããæ¡ä»¶ã«éåããããšãã§ããŸãããJavaScriptã¯æé»çãªå倿ãè¡ãåŸåããããããããã¯ç¹ã«åé¡ã«ãªãå¯èœæ§ããããŸãããã®ãããæååã¯ãæ°å€ãæ³å®ãããŠããå Žåã«ã¯å€±æããŸãããä»ã®å Žæã§ã¯å¿ ç¶çã«å€±æããŸãã
èšèªãµãŒãã¹ã®ãµããŒããæé€
æåã«ã¿ã€ããå²ãåœãŠããããšãTypeScriptèšèªãµãŒãã¹ã¯é©åãªèªå眮æãšã³ã³ããã¹ãããã¥ã¡ã³ããæäŸã§ããŸãïŒå³1.3ïŒã

ãã ããã¿ã€ãanyãæåã«å²ãåœãŠãããšã«ããããã¹ãŠãèªåã§è¡ãå¿ èŠããããŸãïŒå³1.4ïŒã

ãŸããååã倿ŽããŸããååããã©ãŒãããããããã®Personã¿ã€ããšé¢æ°ãããå ŽåïŒ
interface Person {
first: string;
last: string;
}
const formatName = (p: Person) => `${p.first} ${p.last}`;
const formatNameAny = (p: any) => `${p.first} ${p.last}`;
次ã«ããšãã£ã¿ãŒã§æåã«åŒ·èª¿è¡šç€ºãã[ååã®å€æŽ]ã·ã³ãã«ãéžæããŠãååãfirstNameã«å€æŽããŸãïŒå³1.5ããã³å³1.6ïŒã
ããã«ãããformatName颿°ã倿ŽãããŸãããæ¬¡ã®å Žåã¯å€æŽãããŸããã
interface Person {
first: string;
last: string;
}
const formatName = (p: Person) => `${p.firstName} ${p.last}`;
const formatNameAny = (p: any) => `${p.first} ${p.last}`;

»ããã¯ã«ã€ããŠã®è©³çްã¯ãäžã§èŠã€ããããšãã§ããŸãåºç瀟ã®ãŠã§ããµã€ã
Â»ç®æ¬¡
»æç²
ã«ã€ããŠã¯å± äœè ã¯ãŒãã³ã§25ïŒ å²åŒ-掻å
æ¬ã®çŽã®ããŒãžã§ã³ã®æ¯æãã®éãé»åæžç±ã¯ãé»åã¡ãŒã«ã«éä¿¡ãããŸãã