您希望getMovieVersion()
是一个generic函数,其中movie
‘S类型是从constrained到MovieKey
的泛型类型参数K
.
然后,您可以使用K
作为键类型来计算index into typeof movies
,然后使用"versions"
作为键类型来进入结果,最后使用keyof
来获得version
.也就是说,如果movie
是类型K
,则version
是类型keyof (typeof movies)[K]["versions"]
:
declare function getMovieVersion<K extends MovieKey>(
movie: K,
version: keyof (typeof movies)[K]["versions"]
): void;
您可以验证它是否按预期工作:
getMovieVersion("Shawshank Redemption", "Cinema"); // okay
getMovieVersion("The Dark Knight", "Standard"); // okay
getMovieVersion("Shawshank Redemption", "Standard"); // error!
// -----------------------------------> ~~~~~~~~~~
// Argument of type '"Standard"' is not assignable
// to parameter of type '"Cinema" | "Directors Cut"'
如果您还需要明确知道version
的文本类型,以便获得输出的特定类型,则可以使用两个泛型类型参数,如下所示:
declare function getMovieVersion<
MK extends MovieKey,
VK extends keyof (typeof movies)[MK]["versions"]
>(
movie: MK,
version: VK
): (typeof movies)[MK]["versions"][VK];
getMovieVersion("Shawshank Redemption", "Cinema").rating; // error
getMovieVersion("The Dark Knight", "Standard").rating; // okay
Playground link to code个