我只是想知道这在TypeScript中是否可行。想象一下,我有一个定义为联合类型的实体标识符列表:
type EntityID = 'authors' | 'books' | 'programs';
然后,假设我们为这些实体中的每一个都有以下类:
class Author { getBirthday() }
class Book {}
class Program {}
有没有一种方法可以在类型级别实现这一点,以便给定一个具体的EntityID
TypeScript(和我的IDE)知道返回类型是一个具体实体类?类似于:
const book = genericGet('books', 10);
book.getBirthday() // This should fail at COMPILE TIME as it's an Author method
const author = genericGet('authors', 23);
author.getBirthday() // This is OK, as author is an Author
谢谢!
您可以创建从枚举到类型的映射类型,然后使用泛型函数(实际上是工厂方法)来创建对象。
类似的东西:
type EntityID = 'authors' | 'books' | 'programs';
type MapEntity = {
'authors': Author,
'books': Book,
'programs': Program
}
class Author {
getBirthday = ()=>{
}
}
class Book {}
class Program {}
function genericGet<T extends keyof MapEntity>(type: T, ...args: any[]): MapEntity[typeof type] {
switch (type) {
case "authors":
return new Author()
case "books":
return new Book() as any
case "programs":
return new Program() as any
default:
throw Error()
}
}
const book = genericGet('books', 10);
book.getBirthday() // This should fail at COMPILE TIME as it's an Author method
const author = genericGet('authors', 23);
author.getBirthday() // This is OK, as author is an Author
注意事项:
- 使用工厂方法时不需要传递泛型类型,因为TS会推断它
- 您需要为开关指定一个
default
子句,即使那里没有选项。因此TS流分析是令人满意的 - 正确推断了调用
genericGet
的变量的类型
这里是展示这一点的游乐场: