首页 > 解决方案 > 如何知道在 TypeScript 中使用哪种类型?

问题描述

主要问题

我似乎一直在打字稿中以不同的形式遇到这个问题。有时一个函数或某种对象需要一个特定的接口,我正在寻找一组通用的步骤来弄清楚这些接口是什么。

示例代码

我正在尝试编写一个函数来迭代 Material-UI 主题的各种颜色。一旦我开始传递参数来完成这项工作,我什至无法访问个人。

按预期工作

const printColor = () => {
  const theme = createMuiTheme();
  const color = theme.palette.primary['main'];
  console.log(color);
};
printColor(); // prints #3f51b5 to the console

失败的例子

const printColor = (key: string) => {
  const theme = createMuiTheme();
  const color = theme.palette.primary[key];
  console.log(color);
};
printColor('main');

错误:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'PaletteColor'.
  No index signature with a parameter of type 'string' was found on type 'PaletteColor'.

进一步的想法

好像我需要为参数添加某种类型key?我一直在四处寻找,试图弄清楚那会是什么类型。为什么当我直接作为字符串访问它而不是当我将它作为参数传递时它会起作用?

当您遇到这些类型的错误时,有什么方法可以让您快速确定使用哪种类型?

运行代码

根据要求,这里有一个可以自己玩代码的链接。 https://stackblitz.com/edit/typescript-6rntqm

代码在这里运行,但只给出警告。我认为我的 tsconfig 只是设置为失败,但我正在尝试学习如何自己解决这些问题。

标签: typescript

解决方案


所以这个“正确”的答案可能看起来像

import { PaletteColor } from "@material-ui/core/styles/createPalette";

然后稍后

const noLongerFails = (key: keyof PaletteColor) => {
  const theme = createMuiTheme();
  const color = theme.palette.primary[key];
  console.log(color);
};

请注意,我们希望key成为 的键之一PaletteColor,因此我们使用keyof类型运算符将对象类型转换为其键的并集。

追踪正确的PaletteColor类型及其导出位置有点令人讨厌(也许有人有比我更好的解决方案),但它看起来像这样:

  • 将鼠标悬停theme.palette.primary在您的 IDE 中,查看 IntelliSense 对其类型的说明:

    智能感知

    在这种情况下,它说(property) Palette.primary: PaletteColor。因此,如果我们幸运的话,有一种导出的类型叫做PaletteColor.

  • 如果您在node_modules本地安装了 material-ui 的相关信息,则可以搜索该类型。如果没有,您可以随时查看源代码并搜索. 幸运的是,有一个命中,你可以看到它被导出为interfacein styles/createPalette.d.ts

  • 我们从那里进口,它的工作原理!


如果我们找不到合适的导出类型,我们可以开始使用 TypeScript 的类型查询从我们可以导入的东西中梳理出所需的类型:

type MyPaletteColor = ReturnType<typeof createMuiTheme>["palette"]["primary"];

让我们一步一步来。给定一个类似的命名值createMuiTheme,我们可以使用typeof类型查询运算符向 TypeScript 询问它的类型。(不要与运行时运 typeof算符混淆。有关类型名称和值名称之间区别的详细说明,请参阅此答案typeof createMuiTheme)函数类型也是如此:

type CreateMuiThemeType = typeof createMuiTheme;
// type CreateMuiThemeType = (options?: ThemeOptions | undefined, ...args: object[]) => Theme;

现在该函数返回一个Theme. 要获取该类型(假设我们尚未导入它),我们可以使用ReturnType实用程序类型:

type MyTheme = ReturnType<CreateMuiThemeType>;
// type MyTheme = Theme;

最后,我们知道我们要查找的类型是 的primary属性的palette属性Theme。为此,我们可以使用使用索引访问表示法的查找类型:

type MyPalette = MyTheme["palette"];
// type MyPalette = PaletteColor;

type MyPaletteColorAlso = MyPalette["primary"];
// type MyPaletteColorAlso = PaletteColor;

MyPaletteColor我们可以像上面那样将它们折叠成一行。一旦我们有了自己的定义,MyPaletteColor我们就可以使用它来代替PaletteColor

const alsoWorks = (key: keyof MyPaletteColor) => {
  const theme = createMuiTheme();
  const color = theme.palette.primary[key];
  console.log(color);
};

这也有效。


好的,希望有帮助;祝你好运!

Stackblitz 代码链接


推荐阅读