TSのObject、Object、object、{}タイプの違いを1文で読みます.

11943 ワード

「再学習Type Script」のWeChatグループを作成しました.グループの仲間を追加したいです.WeChatを追加してください.
「semlinker」はTSを勉強し直します.
この記事は「TS」シリーズを勉強し直し、27番目の記事です.読んでくれてありがとうございます.
Type Script 2.2は、非元のタイプを表すためにobjectタイプと呼ばれる新しいタイプを導入しています.JavaScriptでは、以下のタイプが元のタイプとみなされます.
他のタイプはすべて非基本型と見なされます.新しいstringタイプは以下の通りです.
// All primitive types
type Primitive = string 
 | boolean | number 
 | bigint | symbol 
 | null | undefined;

// All non-primitive types
type NonPrimitive = object;
booleanタイプを見てみましょう.より正確なタイプの声明を作成するにはどうすればいいですか?
一、objectタイプを使ってタイプ声明を行う
Type Script 2.2のリリースに伴い、標準ライブラリのタイプ宣言は、新しいオブジェクトタイプを使用するために更新されました.例えば、numberおよびビギナートの方法では、これらのプロトタイプパラメータのためにsymbolタイプを指定する必要があります.
// node_modules/typescript/lib/lib.es5.d.ts
interface ObjectConstructor {
  create(o: object | null): any;
  setPrototypeOf(o: any, proto: object | null): any;
  // ...
}
元のタイプをプロトタイプとしてnullまたはundefinedに渡すと、運転中にタイプエラーが発生します.Type Scriptはこれらのエラーをキャプチャし、コンパイル時に対応するエラーを提示します.
const proto = {};

Object.create(proto);     // OK
Object.create(null);      // OK
Object.create(undefined); // Error
Object.create(1337);      // Error
Object.create(true);      // Error
Object.create("oops");    // Error
objectタイプの別の使用例は、ES 2015の一部として導入されたWeakMapデータ構造である.このキーはオブジェクトでなければならず、元の値ではない.この要求は現在、タイプ定義に反映されている.
interface WeakMap {
  delete(key: K): boolean;
  get(key: K): V | undefined;
  has(key: K): boolean;
  set(key: K, value: V): this;
}
二、Object vs object vs{}
困ったことに、Type Scriptはいくつかのタイプを定義しています.似たような名前がありますが、異なる概念を表しています.
  • object
  • Object.create()
  • Object.setPrototypeOf()
  • 上の新しいオブジェクトのタイプを見ました.object | nullObject.setPrototypeOf()の表現について議論しましょう.
    2.1 Objectタイプ
    Type Scriptは、新しいObject.create()タイプとほぼ同じタイプを定義しています.それはobjectタイプです.このタイプはすべてのObjectクラスのインスタンスのタイプです.以下の2つのインターフェースによって定義されます.
  • ObjectインターフェースはObject.prototypeプロトタイプオブジェクト上の属性を定義しています.
  • Object CostructインターフェースはObject類の属性を定義しています.
  • 上記二つのインターフェースの関連定義を紹介します.
    1、objectインターフェース定義
    // node_modules/typescript/lib/lib.es5.d.ts
    
    interface Object {
      constructor: Function;
      toString(): string;
      toLocaleString(): string;
      valueOf(): Object;
      hasOwnProperty(v: PropertyKey): boolean;
      isPrototypeOf(v: Object): boolean;
      propertyIsEnumerable(v: PropertyKey): boolean;
    }
    2、Objectインターフェース定義
    // node_modules/typescript/lib/lib.es5.d.ts
    
    interface ObjectConstructor {
      /** Invocation via `new` */
      new(value?: any): Object;
      /** Invocation via function calls */
      (value?: any): any;
    
      readonly prototype: Object;
    
      getPrototypeOf(o: any): any;
    
      // ···
    }
    
    declare var Object: ObjectConstructor;
    Objectクラスのすべての例はObjectインターフェースのすべての属性を継承しています.パラメータを返す関数を作成すると、次のように見えます.
    Objectオブジェクトに導入された例は、常に関数の返却タイプを満たす.すなわち、戻り値が要求されるのは、toString()方法を含む.
    // Object: Provides functionality common to all JavaScript objects.
    function f(x: Object): { toString(): string } {
      return x; // OK
    }
    {}タイプは、元のタイプではない(undefined、null、bollan、number、bigint、string、smbol)を表しています.このタイプを使うと、値の属性は一切アクセスできません.
    2.2 Object vs Object
    興味深いことに、タイプObjectは、元の値を含む.
    function func1(x: Object) { }
    func1('semlinker'); // OK
    なぜですか?{}の属性は、元の値によってもアクセスできます.
    > 'semlinker'.hasOwnProperty === Object.prototype.hasOwnProperty
    true
    興味のある方は、「JavaScript箱詰めと箱引き」に関する内容を自分で調べてみてください.
    逆に、objectタイプは、元の値を含まない.
    function func2(x: object) { }
    
    // Argument of type '"semlinker"' 
    // is not assignable to parameter of type 'object'.(2345)
    func2('semlinker'); // Error
    なお、Objectタイプの変数に値を割り当てると、値オブジェクト属性名がObjectインターフェースのプロパティと競合する場合、Type Scriptコンパイラは対応するエラーを提示します.
    // Type '() => number' is not assignable to type 
    // '() => string'.
    // Type 'number' is not assignable to type 'string'.
    const obj1: Object = { 
       toString() { return 123 } // Error
    }; 
    Objectタイプにとって、Type Scriptコンパイラは何のエラーも提示されません.
    const obj2: object = { 
      toString() { return 123 } 
    };
    また、Objectタイプと文字列索引オブジェクトタイプの割当を処理する際にも、特に注意してください.
    let strictTypeHeaders: { [key: string]: string } = {};
    let header: object = {};
    header = strictTypeHeaders; // OK
    // Type 'object' is not assignable to type '{ [key: string]: string; }'.
    strictTypeHeaders = header; // Error
    上記の例では、最後のギルドはコンパイルエラーが発生した.ObjectタイプはObjectタイプより正確であるためであり、ObjectConstructor行はエラーを提示していない.この2つのタイプはすべて非基本タイプであり、objectタイプはObjectタイプよりも汎用的である.
    2.3空きタイプ{}
    もう一つのタイプは空のタイプと非常に似ています.つまり、Object.prototype.メンバーがいないオブジェクトを記述しています.このようなオブジェクトの任意の属性にアクセスしようとすると、Type Scriptはコンパイルを作成します.
    // Type {}
    const obj = {};
    
    // Error: Property 'prop' does not exist on type '{}'.
    obj.prop = "semlinker";
    しかし、Objectタイプで定義されたすべての属性と方法は依然として使用できます.これらの属性と方法はJavaScriptのプロトタイプチェーンによって暗黙的に使用できます.
    // Type {}
    const obj = {};
    
    // "[object Object]"
    obj.toString();
    JavaScriptで二次元の座標点を表すオブジェクトを作成するのは簡単です.
    const pt = {}; 
    pt.x = 3; 
    pt.y = 4;
    しかし、上記のコードはType Scriptにおいて、割り当てられたステートメントごとにエラーが発生します.
    const pt = {}; // (A)
    // Property 'x' does not exist on type '{}'
    pt.x = 3; // Error
    // Property 'y' does not exist on type '{}'
    pt.y = 4; // Error
    これは、A行目のptタイプがその値から推測されたもので、既知の属性に対してのみ値を割り当てることができるからです.この問題はどう解決されますか?インターフェースのことを考えている読者がいます.
    interface Point {
      x: number;
      y: number;
    }
    
    // Type '{}' is missing the following 
    // properties from type 'Point': x, y(2739)
    const pt: Point = {}; // Error
    pt.x = 3;
    pt.y = 4;
    残念ですが、上記の案についてはType Scriptコンパイラはまだ間違いを指摘しています.この問題はどう解決すればいいですか?実は直接に対象の字面量によって賦課できます.
    const pt = { 
      x: 3,
      y: 4, 
    }; // OK
    もしあなたが一歩ずつオブジェクトを作成する必要があるなら、タイプ判定(as)を使ってType Scriptのタイプチェックを削除してもいいです.
    const pt = {} as Point; 
    pt.x = 3;
    pt.y = 4; // OK
    しかし、より良い方法は変数の種類を宣言し、オブジェクトを一度に構築することです.
    const pt: Point = { 
      x: 3,
      y: 4, 
    };
    また、object方法を使用して複数のオブジェクトを統合する場合、以下のような問題が発生する可能性があります.
    const pt = { x: 666, y: 888 };
    const id = { name: "semlinker" };
    const namedPoint = {};
    Object.assign(namedPoint, pt, id);
    
    // Property 'name' does not exist on type '{}'.(2339)
    namedPoint.name; // Error
    この場合、上記の問題を解決するためにオブジェクト展開演算子{ [key: string]: string }を使用しても良いです.
    const pt = { x: 666, y: 888 };
    const id = { name: "semlinker" };
    const namedPoint = {...pt, ...id}
    
    //(property) name: string
    namedPoint.name // Ok
    三、対象字面量タイプvsインターフェースタイプ
    オブジェクトはObjectとObjectタイプで記述できるほか、オブジェクトの属性によっても記述できます.
    // Object literal type
    let obj3: { prop: boolean };
    
    // Interface
    interface ObjectType {
      prop: boolean;
    }
    
    let obj4: ObjectType;
    Type Scriptには、オブジェクトの種類を定義する二つの方法があります.それらは非常に似ています.
    // Object literal type
    type ObjType1 = {
      a: boolean,
      b: number;
      c: string,
    };
    
    // Interface
    interface ObjType2 {
      a: boolean,
      b: number;
      c: string,
    }
    以上のコードでは、セパレータとしてセミコロンまたはコンマを使用しています.末尾の区切りは許可されています.また、オプションです.はい、現在問題が発生しました.対象の字面の種類とインターフェースの種類の違いは何ですか?以下の点からそれらの違いを分析します.
    3.1インライン
    対象の字面量のタイプは内連結ができますが、インターフェースはできません.
    // Inlined object literal type:
    function f1(x: { prop: number }) {}
    
    function f2(x: ObjectInterface) {} // referenced interface
    interface ObjectInterface {
      prop: number;
    }
    3.2名前の重複
    重複した名前を含むタイプの別名は不正です.
    // @ts-ignore: Duplicate identifier 'PersonAlias'. (2300)
    type PersonAlias = {first: string};
    
    // @ts-ignore: Duplicate identifier 'PersonAlias'. (2300)
    type PersonAlias = {last: string};
    Type Script 2.6は.tsファイルの中でエラーを報告する行の上で使うことを支持します.objectはエラーを無視する.header = strictTypeHeaders;コメントは次の行で発生したすべてのエラーを無視します.実際にobjectの後に関連するヒントを追加して、どのようなエラーが無視されたかを説明します.
    このコメントはエラーを隠すだけで、このコメントを使わないように勧めます.
    反対に、重複した名前を含むインターフェースはマージされます.
    interface PersonInterface {
      first: string;
    }
    
    interface PersonInterface {
      last: string;
    }
    
    const sem: PersonInterface = {
      first: 'Jiabao',
      last: 'Huang',
    };
    3.3マッピングタイプ
    マッピングタイプ(A行)には、オブジェクトの字面量タイプが必要です.
    interface Point {
      x: number;
      y: number;
    }
    
    type PointCopy1 = {
      [Key in keyof Point]: Point[Key]; // (A)
    };
    
    // Syntax error:
    // interface PointCopy2 {
    //   [Key in keyof Point]: Point[Key];
    // };
    3.4多形thisタイプ
    多形thisタイプはインターフェースにのみ適用されます.
    interface AddsStrings {
      add(str: string): this;
    };
    
    class StringBuilder implements AddsStrings {
      result = '';
      add(str: string) {
        this.result += str;
        return this;
      }
    }
    四、まとめ
    Type Scriptに接触したばかりの読者も多いと思います.Object、object、および{}これらのタイプを見て、疑問を感じます.それらの間にはどんな違いがあるのか分からないので、いつ使いますか?読者にそれらの違いをより直感的に理解させるために、最後にまとめてみます.
    4.1 objectタイプ
    Objectタイプは、Type Script 2.2に導入された新しいタイプで、元のタイプではないことを表すために使用されます.
    // node_modules/typescript/lib/lib.es5.d.ts
    interface ObjectConstructor {
      create(o: object | null): any;
      // ...
    }
    
    const proto = {};
    
    Object.create(proto);     // OK
    Object.create(null);      // OK
    Object.create(undefined); // Error
    Object.create(1337);      // Error
    Object.create(true);      // Error
    Object.create("oops");    // Error
    4.2 Objectタイプ
    Objectタイプ:すべてのObjectクラスの例のタイプです.次の2つのインターフェースによって定義されます.
    これは次の2つのインターフェースによって定義される.
  • ObjectインターフェースはObject.prototypeプロトタイプオブジェクト上の属性を定義しています.
  • // node_modules/typescript/lib/lib.es5.d.ts
    
    interface Object {
      constructor: Function;
      toString(): string;
      toLocaleString(): string;
      valueOf(): Object;
      hasOwnProperty(v: PropertyKey): boolean;
      isPrototypeOf(v: Object): boolean;
      propertyIsEnumerable(v: PropertyKey): boolean;
    }
  • Object CostructインターフェースはObject類の属性を定義しています.
  • // node_modules/typescript/lib/lib.es5.d.ts
    
    interface ObjectConstructor {
      /** Invocation via `new` */
      new(value?: any): Object;
      /** Invocation via function calls */
      (value?: any): any;
    
      readonly prototype: Object;
    
      getPrototypeOf(o: any): any;
    
      // ···
    }
    
    declare var Object: ObjectConstructor;
    ObjectクラスのすべてのインスタンスはObjectインターフェースのすべてのプロパティを継承しています.
    4.3{}タイプ
    {タイプ:メンバーがいないオブジェクトを記述しています.このようなオブジェクトの任意の属性にアクセスしようとすると、Type Scriptはコンパイルされたときにエラーが発生します.
    // Type {}
    const obj = {};
    
    // Error: Property 'prop' does not exist on type '{}'.
    obj.prop = "semlinker";
    しかし、Objectタイプで定義されているすべての属性と方法はまだ使えます.
    五、参考資源
  • the-object-type-i-typescript
  • typing-object s-typescript
  • difference-between-object-and-i-n-typescript
  • 本人の全スタック修仙路購読番号は、定期的にAnglar、Type Script、Node.js/Java、Spring関連の文章を共有します.興味のある仲間は購読します.