用于减少的 TypeScript 类型

rob*_*ert 13 typescript

你将如何正确声明一个类型?

interface MediaQueryProps {
  [key: string]: number;
}

const size: MediaQueryProps = {
  small: 576,
  medium: 768,
  large: 992,
  extra: 1200
};

export default Object.keys(size).reduce((acc, cur) => {
  acc[cur] = `(min-width: ${size[cur]}px)`;

  return acc;
}, {});
Run Code Online (Sandbox Code Playgroud)

acc[cur] 抱怨是因为

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
  No index signature with a parameter of type 'string' was found on type '{}'
Run Code Online (Sandbox Code Playgroud)

有什么方法可以在不使用任何类型的情况下为此声明类型吗?

Tit*_*mir 26

如果您希望累加器值可由 索引string,则Record<string, string>应该这样做。您可以将其作为类型参数传递给reduce

interface MediaQueryProps {
  [key: string]: number;
}

const size: MediaQueryProps = {
  small: 576,
  medium: 768,
  large: 992,
  extra: 1200
};

export default Object.keys(size).reduce<Record<string, string>>((acc, cur) => {
  acc[cur] = `(min-width: ${size[cur]}px)`;
  return acc;
}, {});
Run Code Online (Sandbox Code Playgroud)

游乐场链接


小智 9

使用 TypeScript 4.1,您还可以利用模板文字类型进行as类型转换。TypeScript Playground 链接。

// .ts
interface MediaQueryProps {
  [key: string]: number;
}

const size = {
  small: 576,
  medium: 768,
  large: 992,
  extra: 1200
} as const;

const mediaQueryKeys = Object.keys(size) as Array<keyof typeof size>;

const mediaQueries = mediaQueryKeys.reduce((acc, cur) => {
  acc[cur] = `(min-width: ${size[cur]}px)`;

  return acc;
}, {} as Record<`${keyof typeof size}`, string>);

export default mediaQueries;

// d.ts
declare const mediaQueries: Record<"small" | "medium" | "large" | "extra", string>;
export default mediaQueries;
Run Code Online (Sandbox Code Playgroud)


Pie*_*Duc 8

Record您可以使用and这样做keyof

export default Object.keys(size).reduce((acc, cur) => {
  acc[cur] = `(min-width: ${size[cur]}px)`;

  return acc;
}, {} as Record<keyof MediaQueryProps, string>);
Run Code Online (Sandbox Code Playgroud)