基于属性值的 TypeScript 泛型
我想要有一个接口,其中的泛型类型基于该接口中某个属性的值:
interface Book<T extends BookType> {
type: T,
location: Shelf<T>,
}
而不是使用以下方式来定义泛型类型:
const book: Book<BookType.Technology>;
我想
const book: Book<???>;
book.type = BookType.Technology;
之后,location 被“提示”具有类型 Shelf<BookType.Technology>
在 TypeScript 中这是可能的吗?
答案#1
TypeScript 并不真正支持像你想要的那样先创建空对象然后再赋值属性。通常这里的解决方法是使用类型断言来强类型化空对象……但是你不想自己写出完整类型 Book<BookType.Technology>,所以这不是一个好建议。你希望 BookType.Technology 部分能进行类型推断,但那行不通,因为编译器直到下一行才知道 type 会是 BookType.Technology。而且类型缩小不能向回工作。
在 TypeScript 中的最佳实践是在单个语句中创建一个强类型对象,而不是在多个语句中逐个添加属性。这对编译器来说更容易理解。如果可以的话,我建议使用一个辅助函数,它会为你推断 Book<T> 中的 T。像这样:
const asBook = <T extends BookType>(book: Book<T>) => book;
当你使用它时:
asBook({
type: BookType.Technology,
location: ... // this is hinted as Shelf<BookType.Technology>
})
如你所愿,location 的类型将为你提示为 Shelf<BookType.Technology>。
希望这能帮到你;祝你好运!
代码链接
