Type Script真香シリーズ-高級タイプ


前言
Type Script真香シリーズの内容は中国語の文書を参照しますが、文書の例とほとんど重複しません.一部のところについても深く研究しています.また、いくつかの例の結果は、コードに誤りがない後、JavaScriptにコンパイルされたものです.実際にType Scriptを見たいなら、JavaScriptとしてコンパイルされたコードは、Type Scriptのオンラインアドレスにアクセスして、操作して、より印象的です.
クロスタイプ
クロスタイプは、複数のタイプを1つのタイプに統合し、1つのタイプに相当する動作です.
interface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

let animal: IDog & ICat;
animal = {
    name: "   ",
    age: 1,
    color: "white",
}
animal.name; // "   "
animal.age;  // 1
上のアニマルの属性は一つも欠かせません.属性が足りないと次のエラーが発生します.i
nterface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

let animal: IDog & ICat;
animal = {   //  ,color   ICat     
    name: "   ",
    age: 1,
    // color: "white",
}
結合タイプ
共同タイプは、複数のタイプのうちの1つまたは複数であってもよいということができます.
let a: number | string;
a = 1;
a = "s";
a = false; //   ,  false        number | string
一つのタイプと交差タイプが対応する例を見てください.
interface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

let animal: IDog | ICat; //      &   |
animal = {     //    
    name: "   ",
    age: 1,
    // color: "white",
}
animal.name;
animal.age;
もう一つの例を見ます.
interface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

let animal: IDog | ICat;
animal = {
    name: "   ",
    age: 1,
    color: "white",
}
animal.name;
animal.age; //  ,age    ICat. age    IDog | ICat
上記の例では間違いが見られます.これはType ScriptコンパイラageがIDogかICatか分からないので、共通のname属性にしかアクセスできません.この属性にアクセスしたいなら、どうすればいいですか?私たちはタイプを使って断言できます.
interface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

let animal: IDog | ICat;
animal = {
    name: "   ",
    age: 1,
    color: "white",
}
animal.name;
(animal).age; // 1
これでage属性にアクセスできます.
タイプ保護
私たちは時々次のような場面に遭遇します.
interface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

function animal(arg: IDog | ICat): any {
    if (arg.color) {     //  
        return arg.color  //  
    }
}
しかし、上のコードは間違っています.上記のコードが正常に動作したいなら、連結タイプの例と同じように、使用タイプは断言できます.
interface IDog { 
    name: string,
    age: number,
}
interface ICat {
    name: string,
    color: string
}

function animal(arg: IDog | ICat):any {
    if ((arg).color) {
        return (arg).color;
    }
}
タイプの断言以外にも、タイプの保護を利用して判断することができます.一般的なタイプの保護は三つあります.タイプの保護、instance ofタイプの保護とカスタムタイプの保護です.
typeofタイプ保護
function animal(arg: number | string): any {
    if (typeof arg === "string") {
        return arg + " ";
    }
}
typeofタイプ保護は、2つの形態だけが識別可能である.typeof v === "typename"およびtypeof v !== "typename".「typename」は必ず「number」、「string」、「bollan」または「smbol」でなければなりません.
instance ofタイプ保護
class Dog {
    name: string;
    age: number;
    constructor() { 

    };
}
class Cat {
    name: string;
    color: string;
    constructor() { 

    };
}

let animal: Dog | Cat = new Dog();
if (animal instanceof Dog) {
    animal.name = "dog";
    animal.age = 6;
}
if (animal instanceof Cat) {
    animal.name = "cat";
    animal.color = "white";
}
console.log(animal); //Dog {name: "dog", age: 6}
instance ofの右側の要求は構造関数です.Type Scriptは詳細化されます.
  • このコンストラクタのprototype属性のタイプは、そのタイプがanyでない場合.
  • は、署名によって返されるタイプの結合を構成する.
  • カスタムタイプの保護
    いくつかの複雑な状況に対して、私達はカスタムでタイプの保護を行うことができます.
    interface IDog { 
        name: string,
        age: number,
    }
    interface ICat {
        name: string,
        color: string
    }
    let animal: IDog | ICat;
    animal = {
        name: "   ",
        age: 6,
    }
    function isDog(arg: IDog | ICat): arg is IDog {
    
        return arg !== undefined;
        
    }
    if (isDog(animal)) {
        console.log(animal.age);  //6
    }
    タイプ名
    タイプ別名は、タイプに別名を付けることができます.タイプ別名とインターフェースは似ていますが、また違っています.
    type Name = number;
    type Types = number | string;
    type NAndT = Name & Types;
    type MyFunc = () => number;
    
    function animal(arg: Types) { 
        return arg;
    }
    animal("   "); //"   "
    タイプ別名は、元のタイプ、結合タイプ、汎型などに作用することができます.
    type Dog = { value: T };
    
    function dog(arg: Dog) {
      return arg;
    }
    
    dog({ value: "   " }); //{value: "   "}
    dog({ value: 1});  //  ,  number     string
    dog("   ");  //  ,  “   ”        Dog
    インターフェースとタイプ別名の違い
    違いの1:インターフェースは新しい名前を創建することができて、その上その他のいかなる地方で使うことができます.タイプ別名は新しい名前を作成せずに別名を付けます.区別二:タイプ別名は連携、交差などの操作ができます.違いの3:インターフェースはextensとimplementsと声明に合併されてもいいですが、タイプの別名はいけません.
    ここでは声明の合併を紹介します.
    「声明の統合」とは、コンパイラが同じ名前の2つの独立した声明を単一の声明に統合することを意味します.合併後の声明は、元の二つの声明の特性を同時に持つ.
    どの数量の声明も結合されます.二つの声明に限定されない.
    例を挙げます
    interface IDog {
        name: string;
        setName(arg:string): string;
    }
    
    interface IDog { 
        age: number;
    }
    
    interface IDog { 
        color: string;
    }
    let dog: IDog;
    dog = {
        color: "black",
        age: 6,
        name: "   ",
        setName: (arg) => { 
            return arg
        }
    }
    統合後:
    interface IDog { 
        color: string;
        age: number;
        name: string;
        setName(arg:string): string;
    }
    後ろのインターフェースは合併後に前面に現れたことが分かります.
    文字列の文字数の種類と数字の文字数の種類
    文字列の文字数は文字列を必要とする固定値に指定することができます.
    type Dog = "   " | "  " | "     " | "   ";
    
    function dog(arg: Dog):any { 
      switch (arg) {
        case "   ":
          return "  ";
        case "  ":
          return "    ";
        case "     ":
          return "  ";
        case "   ":
          return "    ";
      }
    }
    dog("   ");  //"  "
    dog("  ");  //  ,  "  "       Dog
    数字の字面は同じである.
    type Num = 1 | 2 | 3 | 4 | 5 | 6 | 7;
    
    function week(arg: Num):any {
      switch (arg) {
        case 1:
          return "   ";
        case 2:
          return "   ";
        case 3:
          return "   ";
        case 4:
          return "   ";
        case 5:
          return "   ";
        case 6:
          return "   ";
        case 7:
          return "   ";
      }
    }
    week(6);  //"   "
    week(8);  //  
    共同を識別することができる
    単一の例のタイプ、結合タイプ、タイプ保護、およびタイプの別名を統合して、識別可能連合という高級なパターンを作成することができます.3つの要素があります.
  • には、一般的な単一のタイプの属性がある.識別可能な特徴.
  • タイプの別名には、それらのタイプの連合が含まれています.
  • この属性のタイプ保護.
  • 次の例を見てもいいです.
    //              ,              ,
    //      kind   (            )              
    interface IColor {
      kind: "color";
      value: string;
    }
    
    interface ISize {
      kind: "size";
      height: number;
      width: number;
    }
    
    //                         
    type MyType = IColor | ISize;
    
    //         
    function types(arg: MyType) :any{
      switch (arg.kind) {
        case "color":
          return arg.value;
        case "size":
          return arg.height * arg.width;
      }
    }
    types({ kind: "color", value: "blue" });  //"blue"
    types({ kind: "size", height: 10, width: 20 }); //200
    索引の種類
    索引の種類を使うと、コンパイラは動的属性名を使用したコードを確認することができます.私たちはまず二つの操作符を知りたいです.
  • インデックスタイプのクエリオペレータkeyof Tは、任意のタイプのTについて、keyof Tの結果は、T上で知られている共通属性の組み合わせであるという意味である.
  • インデックスアクセス演算子T[K].
  • interface IDog{
      a: string,
      b: number,
      c: boolean,
    }
    
    let dog: keyof IDog; //let dog: "a" | "b" | "c"
    let arg: IDog["a"];  //let arg: string
    もっと複雑な例を見てください.
    interface IDog{
      name: string,
      age: number,
      value: string,
    }
    
    let dog: IDog;
    dog = {
      name: "  ",
      age: 6,
      value: "   "
    }
    
    function myDog(x: T, args: K[]): T[K][] { 
      return args.map(i => x[i]);
    }
    
    myDog(dog, ['name']);  //["  "]
    myDog(dog, ['name', 'value']);  //["  ", "   "]
    myDog(dog, ['key']);  //  ,     
    マップのタイプ
    時々私たちはこのような状況に会うことができます.各メンバーをオプションまたは読み取り専用に変えます.
    interface Person{
        name: string;
        agent: number;
    }
    
    interface PersonPartial {
        name?: string;
        age?: number;
    }
    
    interface PersonReadonly {
        readonly name: string;
        readonly age: number;
    }
    これはJavaScriptによく登場します.Type Scriptは古いタイプから新しいタイプを作成する方法ーマッピングタイプを提供します.マッピングのタイプでは、新しいタイプは同じ形式で古いタイプの各属性を変換します.
    interface IPerson{
        name: string;
        agent: number;
    }
    
    type OPartial = {
        [P in keyof T]?: T[P];
    }
    
    type OReadonly = {
        readonly [P in keyof T]: T[P];
    }
    //    
    type PersonPartial = OPartial;
    type ReadonlyPerson = OReadonly;
    参照
    https://github.com/zhongsp/Ty... https://github.com/jkchao/typ...
    最後に
    文章の中には自分の理解を入れるところがあります.正確でないところや間違っているところがあれば、ご指摘ください.