【发布时间】:2019-08-12 13:48:44
【问题描述】:
我的问题有点复杂,所以这里可能是所有必需的部分:
// Common interface with an id and a string lieral type
interface IHandler {
id: Id<IHandler>;
type: string;
}
// Base class for all the handler, with generic argument providing string literal type and access to inheriting type
class Base<Type extends string, T extends Base<Type, T>> implements IHandler {
id: Id<T> = Guid.raw() as any
// In consturctor string literal type is instantiated
protected constructor(public type: Type) {
this.type = type;
}
// Static function that retrieves handler by it's key from a store
static GetHandler: <T extends IHandler>(get: Id<T>) => T;
// Getter that accepts key of an id attribute and returns instance from store
get = <Handler extends Base<Handler["type"], Handler>>(key: HandlerIds<T, Handler>) => Base.GetHandler<Handler>((this as any)[key]);
}
// Keys of attributes that are Id's
type HandlerIds<T extends Base<T["type"], T>, U extends Base<U["type"], U>> = keyof SubType<Model<T>, Id<U>>;
// Creates a subtype based on condition
type SubType<Base, Condition> = Pick<Base, { [Key in keyof Base]: Base[Key] extends Condition ? Key : never }[keyof Base]>;
// Excludes attributes of Base
type Model<T extends Base<T["type"], T>> = Partial<Pick<T, Exclude<keyof T, keyof Base<T["type"], T>>>>;
// Type that holds guid reference and also a type that guid is supposed to be pointing to
type Id<T extends IHandler> = string & { __type: T }
所以我有一个interface,然后是一个实现getter 的base 类,然后是将其类型传递给基类的派生类。还有一个Id 类型,它保存处理程序的唯一标识符以及它的类型。每个处理程序在 id 变量中都有自己的 id,然后可以使用该处理程序类型的通用参数将对其他处理程序的引用保存在 Id 类型的属性中。
我想做的是正确键入get 函数,以便它推断它通过提供的key 获得的处理程序的类型。由于每个键都是按其指向的处理程序类型模板化的,因此可能应该使用这种类型来推断返回类型,但是像这样的设置它不起作用。
您可以在此处查看所需用法的示例:
class Foo extends Base<"Foo", Foo> {
a: Id<Goo>;
b: Id<Foo>;
constructor() {
super("Foo");
// Get a reference to instance of "a" of type Goo
var aHandler = this.get("a");
// Get a reference to instance of "b" of type Foo
var bHandler = this.get("b");
}
}
class Goo extends Base<"Goo", Goo> {
constructor() {
super("Goo");
}
}
我想在这里实现的是属性aHandler和bHandler被自动推断为Foo和Goo。
【问题讨论】:
-
cmets 的代码很多 ;)。
标签: typescript type-inference typescript-generics