Typescript: ジェネリックでtypeofを使用する

作成日 2017年12月15日  ·  3コメント  ·  ソース: microsoft/TypeScript

TypeScriptバージョン:現在の遊び場バージョン(?)

コード

class GenericGroup<T> {
  items: Array<T> = [];
  constructor(name: string) {}
}

type CheckboxValues = string;
type CheckboxesGroup = new (name: string) => GenericGroup<CheckboxValues>;
const Checkboxes: CheckboxesGroup = GenericGroup;
const checkboxes = new Checkboxes('checkboxes');
checkboxes.items.map(item => item.toUpperCase());


type RadioValues = string;
type RadiosGroup = typeof GenericGroup<RadioValues>;
const Radios: RadiosGroup = GenericGroup;
const radios = new Radios('radios');
radios.items.map(item => item.toUpperCase());

リンク

予想される行動:

typeof GenericGroup<RadioValues>;new (name: string) => GenericGroup<RadioValues>;と同等です

実際の動作:

typeof GenericGroup<RadioValues>;がサポートされていないため、構文エラー。

動機:

私のユースケースでは、サードパーティのライブラリからクラスを_拡張_するジェネリック( GenericGroup )を持つクラスがあります。 サードパーティのlibのクラスは、コンストラクターで複数のパラメーターを使用します。 塗りつぶされたジェネリックでクラスのエイリアスを作成するとき、サードパーティのライブラリのパラメータを毎回記述したくありません( new (name: string) => GenericGroup<CheckboxValues>;行われるように)。実際にはそれらを維持していません。

(複数の関連する問題があるようですが、正確にこの問題に関する問題は見つかりませんでした。)

Question

最も参考になるコメント

'typeof'演算子は、型のコンストラクターを説明するためのものではなく、値の型を説明するためのものです。 SomeGenericは値ではなく、それ自体が型です。 他のインターフェース/タイプ(以下に定義されているものなど)もこの方法では機能しません。

interface MyInterface {
    name: string;
}

let m: typeof MyInterface; // error "MyInterface only refers to a type, but is being used as a value here."

これに対する解決策は、Angularのようにコンストラクターを記述するジェネリック型を定義することです。

// angular/packages/core/src/type.ts

export interface Type<T> extends Function { 
    new (...args: any[]): T; 
}

from( angular / packages / core / src / type.ts

使用例:

type RadioValues = string;
type RadiosGroup = Type<GenericGroup<RadioValues>>;
const Radios: RadiosGroup = GenericGroup;
const radios = new Radios('radios');
radios.items.map(item => item.toUpperCase());

全てのコメント3件

'typeof'演算子は、型のコンストラクターを説明するためのものではなく、値の型を説明するためのものです。 SomeGenericは値ではなく、それ自体が型です。 他のインターフェース/タイプ(以下に定義されているものなど)もこの方法では機能しません。

interface MyInterface {
    name: string;
}

let m: typeof MyInterface; // error "MyInterface only refers to a type, but is being used as a value here."

これに対する解決策は、Angularのようにコンストラクターを記述するジェネリック型を定義することです。

// angular/packages/core/src/type.ts

export interface Type<T> extends Function { 
    new (...args: any[]): T; 
}

from( angular / packages / core / src / type.ts

使用例:

type RadioValues = string;
type RadiosGroup = Type<GenericGroup<RadioValues>>;
const Radios: RadiosGroup = GenericGroup;
const radios = new Radios('radios');
radios.items.map(item => item.toUpperCase());

微妙なことは、ジェネリッククラスのコンストラクター関数がジェネリック型に含まれていないことです。 typeパラメーターが静的メンバーのスコープ内にないため、それがわかります。 このようなタイプのように「感じる」

interface GenericCtor<T> {
  new(x: string): InstanceType<T>;
}

でも本当のタイプはこんな感じ

interface GenericCtor {
  new<T>(x: string): InstanceType<T>;
}

あなたがた両方に感謝します。 これに頭を巻く必要があります。 私の場合、サードパーティのコンストラクター( React.Component )から拡張しているので、そこでフィードバックを適用する方法を理解する必要があります。 ありがとう。

このページは役に立ちましたか?
0 / 5 - 0 評価