我正在try 使用2个键的组合从对象中的特定树叶检索数据.我在正确键入用于访问嵌套对象的键(S)时遇到问题.

给定此宾语 struct

const movies = {
  "Shawshank Redemption": {
    rating: 9,
    versions: {
      "Directors Cut": {
        length: 111,
      },
      Cinema: {
        length: 113,
      },
    },
  },
  "The Dark Knight": {
    release: 2008,
    versions: {
      Standard: {
        rating: 9,
        length: 113,
      },
    },
  },
};
type MovieKey = keyof typeof movies;

如何才能在此方法中正确键入VersionKey?这有可能吗?

function getMovieVersion(movie: MovieKey, version: VersionKey)

推荐答案

您希望getMovieVersion()是一个generic函数,其中movie‘S类型是从constrainedMovieKey的泛型类型参数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

Typescript相关问答推荐

如何在类型脚本中声明对象其键名称不同但类型相同?

如何在TypeScript对象迭代中根据键推断值类型?

React typescribe Jest调用函数

泛型类型,引用其具有不同类型的属性之一

创建一个根据布尔参数返回类型的异步函数

隐式键入脚本键映射使用

返回具有递归属性的泛型类型的泛型函数

如何使默认导出与CommonJS兼容

用于验证字符串变量的接口成员

使用Redux Saga操作通道对操作进行排序不起作用

`fetcher.load`是否等同于Get Submit?

如何过滤文字中的类对象联合类型?

如何在脚本中输入具有不同数量的泛型类型变量的函数?

类型推断对React.ForwardRef()的引用参数无效

Rxjs将省略的可观测对象合并到一个数组中

可赋值给类型的类型,从不赋值

如何限定索引值必须与相应属性的id字段相同

为什么 Typescript 无法正确推断数组元素的类型?

如何在没有空接口的情况下实现求和类型功能?

为什么在 useState 中设置 React 组件是一种不好的做法?