TypeScriptã§å½¢å¼ç証æãåãå ¥ããããã°ã©ãã³ã°ãå®è·µãã¾ãã
å½¢å¼ç証æã¨ã¯ãä»æ§ã¾ãã¯ã¢ãã«ãæ°çè«çå¦çã«æ£ãããã®ã§ããå®è£ å¯è½ã§ãããã¨ã®å½¢å¼ææ³ã«ãã証æã§ãã æ¬ç¨¿ã§ã¯å½¢å¼ææ³ã®ãã¡ãåã·ã¹ãã ãå©ç¨ãã軽éå½¢å¼ææ³ã«ããå½¢å¼ç証æãæ±ãã¾ãã
ãã®è¨äºã¯TypeScript ã¢ããã³ãã«ã¬ã³ãã¼2015 1æ¥ç®ã®è¨äºã§ãã
TypeScriptã¢ããã³ãã«ã¬ã³ãã¼2015ï¼ï¼
å»å¹´ããã ãããæ¦å£«ãã¡ã¯ã©ãã¸è¡ã£ãã®ãâ¦
ãã¦ãå½¢å¼ç証æãå®æããããã«1ã¤ã®ã³ã¼ãã¢ã¸ã¥ã¼ã«ãä½ã£ã¦ã¿ã¾ãããã
ãããããã®çµæãã°ã¼ã»ãã§ãã»ãã¼ã®3ã¤ã®åã使ã£ã¦åæ¨è«ã ãã§è¨ç®ããä¸æ£ãªå ¥åãå®è¡åã«æ¤åºãããå½¢å¼ç妥å½æ§ã®è¨¼æãããã³ã¼ãã¢ã¸ã¥ã¼ã«ã§ãã
ã¾ãåæã¨ãªãã°ã¼ã»ãã§ãã»ãã¼ã®3ã¤ã®åãä½ãã¾ãã
class Gu { private identity; } class Choki { private identity; } class Pa { private identity; }
TypeScriptã®åã¯æ§é çé¨ååã ããåãåºå¥ã§ããªãã¨æã£ã¦ãã¾ãããï¼ TypeScriptã«ã¯åãä¸æã«èå¥ããæ¹æ³ãç¨æããã¦ãããæ§é çé¨ååã¨å ¬ç§°çé¨ååã®ä¸¡æ¹ããµãã¼ããã¦ãã¾ãã
ã¢ã¯ã»ã·ããªãã£ä¿®é£¾åã«privateã¾ãã¯protectedãæå®ããã¨ãã®ã¡ã³ãã¼ãä»ã§å®ç¾©ãããååã®ã¡ã³ãã¼ã«ä»£å ¥ã§ããªãä¸æãªèå¥åã¨ãªãã¾ãã
ããã«ããTypeScriptã§ãå ¬ç§°åã¾ãã¯å ¬ç§°çé¨ååã§ããä»»æã®ä»£æ°çãã¼ã¿åã¨ãã®ç´ååãä½ããã¨ãã§ããã®ã§ãï¼æ°å¦çã«ã¯å ±éé¨åã®ãªãåå士ã«éããã¾ããå®ç¨ä¸ã¯æ°ã«ããå¿ è¦ã¯ãªãã§ãããï¼ã
ã¾ããTypeScriptã®Union typesã¯ç´ååãã®ãã®ã§ã¯ããã¾ãããç´ååã¨ãã¦ã®ä½¿ãæ¹ãã§ããã®ã§TypeScriptã§ãç´ååã®æ¦å¿µã«åºã¥ããããã°ã©ãã³ã°ãå¯è½ã§ãã
次ã«ã°ã¼ã¨ãã§ããªãã°ã¼ãåã¤ã¨ãã£ãè«çï¼è¦åã»ä»æ§ï¼ãä½ãã¾ãã
interface Rule<T, U> { (a: T, b: U): T; (b: U, a: T): T; } interface Fight<T, U, V> extends Rule<T, U>, Rule<U, V>, Rule<V, T> { } var fight: Fight<Gu, Choki, Pa> = (a: Options, b: Options): any => void 0; type Options = Gu|Choki|Pa;
æå¾ã«ãããã®ä»æ§ã®å¦¥å½æ§ç¢ºèªãè¡ãããªãã¼ã·ã§ã³ã³ã¼ããæ¸ãã¦æ£ããæ©è½ãã¦ããã確èªãã¾ãã
<Gu>fight(new Gu, new Choki); <Pa>fight(new Gu, new Pa); ...
ããã§å®æã§ãããã£ãã試ãã¦ã¿ã¾ãããã
var correctWinner: Gu = fight(new Gu, new Choki); var incorrectWinner: Choki|Pa = fight(new Gu, new Choki); // type error
ã¡ããã¨åãã¦ã¾ãããåã ãã§çµæãå¾ãããã®ã§åé¡ã«ãã£ã¦ã¯ã¢ã«ã´ãªãºã ãå®è£ ããã«æ£ããçããå¾ããã¨ããå¯è½ã§ãã
var winner: Gu = fight(new Gu, new Choki) || new Gu;
åãè¦ã¦ããçµæããã¼ãã³ã¼ãã£ã³ã°ä½è£ã§ããããã¹ãã§ã«ã³ãã³ã°ãã¦éä¸è¨ç®ãæ¸ããã«çãã ãæ¸ããããªãã®ã§ããã
ã§ãããã ãã§ã¯ã¤ã¾ããªãã®ã§ãã£ã¨ãµã¤ãºã大ãããã¦ã¿ã¾ããããããããããã¼ãã¡ã³ããéå¬ãã¦ã¿ã¾ãã
ã°ã¼ã»ãã§ãã»ãã¼ã®åã¤ã³ã¹ã¿ã³ã¹ãåã ã®é¸æï¼ã®æåã®æï¼ã¨ãªãã¾ããé¸æãåºå¥ãããå ´åã¯ã³ã³ã¹ãã©ã¯ã¿ãåæåãã©ã¡ã¼ã¿ãåãåãããã«ãã¦é¸æåãªã©ã§é¸æãåºå¥ã§ããããã«ãã¾ãããããã®ããã«å®ä½ãåºå¥ããå¿ è¦ãããã¨ãã¯ãã£ãã®ãããªããã¯ã§ãã¾ããã
// 2åæ¦ fight( fight(new Gu, new Choki), fight(new Choki, new Pa) ); // Gu
// 3åæ¦ fight( fight( fight(new Gu, new Choki), fight(new Choki, new Pa) ), fight( fight(new Gu, new Pa), fight(new Choki, new Gu) ) ); // Pa
åé¡ãªããã¼ãã¡ã³ããæç«ãããã¨ã証æããã¦ãã¾ããã
ã¨ã¯ããâ¦
fight( fight(new Gu, new Pa), fight(new Pa, new Gu) ); // type error
Oops! ã¨ã©ã¼ã«ãªãã¾ãããããã¼ã«ãªãåã¡è² ãã決ã¾ããªãå ´åãèæ ®ãã¦ããªãã£ãã®ã§ãã
å½¢å¼ç証æãè¡ã£ã¦ãéç¶²ç¾ çå®ç¾©ã¾ã§ãã©ãã¼ãã¦ãããã¨ã¯éãã¾ãããHaskellãªã©ä¸é¨ã®ããã°ã©ãã³ã°è¨èªã¯å®ç¾©ã®ç¶²ç¾ æ§ãæ¤è¨¼ãã¦ããã¾ããç¶æ é·ç§»ããã¹ã¦ã®çµã¿åããã«ããã¦ç ´ç¶»ãªã循ç°ãããã¨ã¾ã§ã¯æ¤è¨¼ãã¦ããã¾ãããå½¢å¼ç証æç¨ã®è¨èªããã¼ã«ã§ããã°ããããç¶²ç¾ çãªæ¤è¨¼ãå®æ½ããæ©è½ãåãã¦ãã¾ãããé常ã®ããã°ã©ãã³ã°è¨èªã®åã·ã¹ãã ãå©ç¨ããã ãã§ã¯ããããæ¬æ ¼çãªæ¤è¨¼ã¾ã§ã¯è¡ããªãã®ã§ããããã¾ã§ã½ã¼ã¹ã³ã¼ãä¸ã§å ·ä½çã«ç¤ºãããçµã¿åããã®ä¸ã§ã®æ¤è¨¼ã¨ãªããå ¥åããåã誤ã£ãå®è£ ãå®è£ ä¸å¯è½ãªä»æ§ãã¢ãã«ãä½ããªãããã®æ¤è¨¼ã§ããã¾ãããããã«ãã¦ãæ ¹æ¬çå®ç¾©ãã¹ã«ã¯ç¡åãªã®ã§éä¿¡ã¯ç¦ç©ã§ãã
ãããããã¼ãã¡ã³ãã«æ¬ é¥ãããæç«ããªããã¨ã¯äºåã«å¤æãã¾ããããããå®è£ ã¢ã«ã´ãªãºã ã«é¢ä¿ãªãããã¹ãã±ã¼ã¹ã®ç¯å²å¤ã§ãã£ã¦ãã§ãï¼å½¢å¼çã«æ£ãããã¨ã確èªãã妥å½æ§ç¢ºèªã¯è¡ãã¾ããããå®è£ ã®æ£ãããæ¤è¨¼ãããé常ã®ãã¹ãã«è©²å½ããæ£å½æ§æ¤è¨¼ã¯è¡ã£ã¦ãã¾ããããªã«ããå®è£ ã空ã§ããããï¼ããã¼ãã¡ã³ãä¸ã«çºè¦ãã¦èè¡ãä¸æ¢ããããããªããªãã大ãã¼ã¤ã³ã°ãæµ´ã³ãªããåºè³è ããã®æ³ç責任追åã¨éå£è¨´è¨ã«æ¯ãããããã»ã©ã¾ãã§ãããããããå½¢å¼ææ³ã¨å½¢å¼ç証æã®å¨åã§ãããã®æ¬ é¥ã®å¤æãåãã¦ãã¼ãã¡ã³ããæç«ãããããã«ãã¼ãã¡ã³ããä¸æç«ã¨ãªãçµã¿åãããèªããªãããããã¼ã®è§£æ±ºæ¹æ³ãå®ç¾©ãããã¯ä¸»å¬è ãã ãã§ãã
以ä¸ã®ããã«ããã®ã±ã¼ã¹ã§ã¯å½¢å¼ç証æãå°å ¥ãããã¨ã§å¤§ããªææãä¸ãããã¨ãã§ãã¾ãããå®ç¾©ã¨éç¨ã®ç¯å²å ã§åä½å¯è½ã§ãããã¨ãæ°çè«çå¦çã«è¨¼æãããéã«ä¸å¯è½ã§ããå ´åã¯ãããæ¤åºãã¦ã³ã³ãã¤ã«ã®æ®µéã§åã¨ã©ã¼ã¨ãã¦åºåããæå¾ éãæ£ããæ©è½ããããã§ãã
宣è¨çã§ç°¡æ½ãªåã«ããæ½è±¡åãããæ¤è¨¼ã¨è¨¼æã¯ãã¢ã«ã´ãªãºã ã®å®è£ å¯è½æ§ã¨ãã尺度ããã½ã¼ã¹ã³ã¼ãä¸ã®ä»æ§ãªããã¢ãã«ã®è©ä¾¡ãå¯è½ã«ã*1ãæç¶ãçã«ãªããããè¤éãªå®è£ ã¢ã«ã´ãªãºã ã®é¨åçãã¹ããããé«æ°´æºãªä¿¡é ¼æ§ã®ææ¨ã¨ãªãã¾ã*2ã
éçåä»ãè¨èªã¯éçåã«ããåçåä»ãè¨èªãããæ©ã段éã§å®è£ ã®æ£ãããæ¤æ»ãã¦å質ã¨ä¿¡é ¼æ§ãé«ãã¦ãã¾ããããå½¢å¼ç証æã¯ããã«æ©ããå®è£ åã®æ®µéã§æ½è±¡åãããä»æ§ãã¢ãã«ãæ¤è¨¼ãã¦ããã®ã§ãã
ãã®ããã«å½¢å¼ç証æã¯ã³ã¼ãã®å質ã¨ä¿¡é ¼æ§ã®åä¸ã«å¤§ããå½¹ç«ã¤ãã®ã§ããæ¯å¹´æ°ãããã¬ã¼ã ã¯ã¼ã¯ãè¦ãã¦ã¯ä½¿ãæ¨ã¦ãããå½¢å¼ææ³ã1ã¤è¦ããã»ãããã»ã©ã«ã¹ãã«ã¨ã³ã¼ãå質ãåä¸ãã¾ããå½¢å¼ç証æã¯ãã®ãã10å¹´ã§ã20å¹´ã§ãçãã¤ã¥ããå®å®ããæè¡åéã§ããã¿ãªããããã²ä½¿ã£ã¦ã¿ã¦ãã ããã
TypeScriptã¢ããã³ãã«ã¬ã³ãã¼2015ã次åã¯äº¤å·®åã使ã£ã¦åã«ç¶æ ãåçã«ä»ä¸ããå½¢å¼ç証æï¼äº¤å·®åç·¨ï¼ã§ããã楽ãã¿ã«ã
æ¬ç¨¿ã«æ²è¼ããã³ã¼ãã¯ä»¥ä¸ã®ãªã³ã¯å ã§å½¢å¼çåä½ã確èªã§ãã¾ãã
*1:å¯ä½ç¨ã ããã®è¨èªã§ãåã®ä¸çã§ã¯å½¢å¼ç証æã«é©ããç´ç²é¢æ°ããã°ã©ãã³ã°ãå®ç¾ã§ããã®ã§ãã
*2:å½¢å¼ç証æã¯å ¥åºåã®å以ä¸ã®å®è£ ã®æ£ããããã¹ãããªãã®ã§å®è£ ã®ãã¹ããä¾ç¶ã¨ãã¦å¿ è¦ã§ãã