0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reflect.getMetadata("design:type", ...)で得られる型まとめ

Posted at

検証環境

バージョン

library version
Node.js v16.13.1
Typescript v4.5.4
reflect-metadata v0.1.13

tsconfig.json

必要な設定を有効化しておく。

{
  "experimentalDecorators": true,
  "emitDecoratorMetadata": true
}

検証方法

jestテストファイルに型チェックできるProperty Decoratorを用意した。
別にDecoratorにする必要はないがプロパティ定義と得られる型をまとめて記述できて都合がよかった。

function CheckType(expectedType: any): PropertyDecorator {
  return function (target: Object, propertyKey: string | symbol) {
    const reflectedType: Function = Reflect.getMetadata(
      'design:type',
      target,
      propertyKey
    );

    expect(reflectedType).toBe(expectedType);
  };
}

class Test {
  @CheckType(String) s: string;
}

結果

プロパティ定義 expectedType 備考
prop: string String
prop: number Number
prop: Boolean Boolean
prop: true Boolean
prop: Date Date
prop: Symbol Object
prop: Map Map ジェネリック型の内容まではわからない
prop: Set Set
prop: SomeClass SomeClass
prop: SomeInterface Object interface SomeInterface {}
prop: ObjectType Object type ObjectType = {};
prop: StringType String type StringType = '';
prop: Function Function
prop: () => string Function
prop: string[] Array
prop: [string, number] Array
prop: {} Object
prop: Object Object
prop: NumberEnum Number enum NumberEnum { A = 0, B }
prop: StringEnum String enum StringEnum { A = 'a', B = 'b' }
prop: MixEnum Object enum MixEnum { A = 'a', B = 1 } : union型と同様?
prop Object 型定義なし
prop = '' Object 初期化していても型定義が無ければObjectになる
prop: null undefined
prop: undefined undefined
prop: any Object
prop: unknown Object
prop: void undefined
prop: never undefined
prop: string | number Object
prop: 'a' | 'b' String union型
prop: string | null String
prop: string | undefined String
prop: string | any Object
prop: string | unknown Object
prop: string | void Object
prop: string | string[] Object
prop: string & number Object
prop: 'a' & 'b' String intersection型。調べた範囲ではunionと同じ結果
prop: string & null String
prop: string & undefined String
prop: string & any Object
prop: string & unknown Object
prop: string & void Object
prop: string & string[] Object
prop: T Object class Test<T>
prop: T2 String class Test<T extends string>

検証コード全体

import 'reflect-metadata';

function CheckType(expectedType: any): PropertyDecorator {
  return function (target: Object, propertyKey: string | symbol) {
    const reflectedType: Function = Reflect.getMetadata(
      'design:type',
      target,
      propertyKey
    );

    expect(reflectedType).toBe(expectedType);
  };
}

describe('Reflect.getMetadata("design:type")', () => {
  test('', () => {
    class SomeClass {}
    interface MyInterface {}
    type ObjectType = {};
    type StringType = '';
    type UnionType1 = string | number;
    type UnionType2 = 'a' | 'b';
    type IntersectionType = string & number;

    enum NumberEnum {
      A = 0,
      B,
    }

    enum StringEnum {
      A = 'a',
      B = 'b',
    }

    enum MixEnum {
      A = 'a',
      B = 1,
    }

    class Test<T, T2 extends string> {
      @CheckType(String) prop0: string;
      @CheckType(String) prop1: string = '';
      @CheckType(Number) prop2: number;
      @CheckType(Boolean) prop3: Boolean;
      @CheckType(Boolean) prop4: true;
      @CheckType(Date) prop5: Date;
      @CheckType(Object) prop6: Symbol;
      @CheckType(Map) prop7: Map<number, string>;
      @CheckType(Set) prop8: Set<string>;
      @CheckType(SomeClass) prop9: SomeClass;
      @CheckType(Object) prop10: MyInterface;
      @CheckType(Object) prop11: ObjectType;
      @CheckType(String) prop12: StringType;
      @CheckType(Function) prop13: Function;
      @CheckType(Function) prop14: () => string;
      @CheckType(Array) prop15: string[];
      @CheckType(Object) prop16: {};
      @CheckType(Object) prop17: Object;
      @CheckType(Object) prop18: unknown;
      @CheckType(Object) prop19: any;
      @CheckType(Number) prop20: NumberEnum;
      @CheckType(String) prop21: StringEnum;
      @CheckType(Object) prop22: MixEnum;
      @CheckType(Object) prop23: string | number;
      @CheckType(String) prop24: 'a' | 'b';
      @CheckType(String) prop25: string | undefined;
      @CheckType(Object) prop26: string | void;
      @CheckType(String) prop27: string | null;
      @CheckType(Object) prop28: string | any;
      @CheckType(Object) prop29: string | unknown;
      @CheckType(Object) prop30: string | string[];
      @CheckType(Object) prop31: string & number;
      @CheckType(String) prop32: 'a' & 'b';
      @CheckType(String) prop33: string & undefined;
      @CheckType(Object) prop34: string & void;
      @CheckType(String) prop35: string & null;
      @CheckType(Object) prop36: string & any;
      @CheckType(Object) prop37: string & unknown;
      @CheckType(Object) prop38: string & string[];
      @CheckType(Array) prop39: [string, number];
      @CheckType(undefined) prop40: void;
      @CheckType(undefined) prop41: never;
      @CheckType(Object) prop42;
      @CheckType(Object) prop43 = '';
      @CheckType(undefined) prop44: null;
      @CheckType(undefined) prop45: undefined;
      @CheckType(Object) prop46: T;
      @CheckType(String) prop47: T2;
    }
  });
});
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?