Введите переменную, которая будет одним из ключей на карте? - PullRequest
2 голосов
/ 14 апреля 2020

У меня есть карта и функция. Я хочу, чтобы функция принимала в качестве параметра любую из клавиш на карте. Мой код ниже не работает. keyof typeof svgAttributeToCssStyle - это "clear" | "delete" | "forEach" | "get" | ..., а не ["alignment-baseline", "baseline-shift", ...], как мне бы хотелось.

Карта:

const svgAttributeToCssStyle = new Map<string, keyof CSSStyleDeclaration>([
  ["alignment-baseline", "alignmentBaseline"],
  ["baseline-shift", "baselineShift"],
  ["clip", "clip"],
  ["clip-path", "clipPath"],
  ["color", "color"],
  ["color-interpolation", "colorInterpolation"],
  ["color-interpolation-filters", "colorInterpolationFilters"],
  ["cursor", "cursor"],
  ["direction", "direction"],
  ["display", "display"],
  ["dominant-baseline", "dominantBaseline"],
  ["enable-background", "enableBackground"],
  ["fill", "fill"],
  ["fill-opacity", "fillOpacity"],
  ["fill-rule", "fillRule"],
  ["filter", "filter"],
  ["flood-color", "floodColor"],
  ["flood-opacity", "floodOpacity"],
  ["font-family", "fontFamily"],
  ["font-size", "fontSize"],
  ["font-size-adjust", "fontSizeAdjust"],
  ["font-stretch", "fontStretch"],
  ["font-style", "fontStyle"],
  ["font-variant", "fontVariant"],
  ["font-weight", "fontWeight"],
  ["glyph-orientation-horizontal", "glyphOrientationHorizontal"],
  ["glyph-orientation-vertical", "glyphOrientationVertical"],
  ["image-rendering", "imageRendering"],
  ["kerning", "kerning"],
  ["letter-spacing", "letterSpacing"],
  ["lighting-color", "lightingColor"],
  ["marker-end", "markerEnd"],
  ["marker-mid", "markerMid"],
  ["marker-start", "markerStart"],
  ["mask", "mask"],
  ["opacity", "opacity"],
  ["overflow", "overflow"],
  ["pointer-events", "pointerEvents"],
  ["shape-rendering", "shapeRendering"],
  ["stop-color", "stopColor"],
  ["stop-opacity", "stopOpacity"],
  ["stroke", "stroke"],
  ["stroke-dasharray", "strokeDasharray"],
  ["stroke-dashoffset", "strokeDashoffset"],
  ["stroke-linecap", "strokeLinecap"],
  ["stroke-linejoin", "strokeLinejoin"],
  ["stroke-miterlimit", "strokeMiterlimit"],
  ["stroke-opacity", "strokeOpacity"],
  ["stroke-width", "strokeWidth"],
  ["text-anchor", "textAnchor"],
  ["text-rendering", "textRendering"],
  ["transform", "transform"],
  ["unicode-bidi", "unicodeBidi"],
  ["visibility", "visibility"],
  ["word-spacing", "wordSpacing"],
  ["writing-mode", "writingMode"],
]);

функция:

export function getPresentationAttribute(attribute: keyof typeof svgAttributeToCssStyle) {
  ...
}

Как можно Я делаю это?

1 Ответ

2 голосов
/ 14 апреля 2020

Если вы явно указали тип ключа карты как string TS не сохранит тип ключа.

Если вы позволите TS выводить тип ключа и также используете утверждение as const в исходном массиве карты, то TS сохранит в типе карты фактические литеральные типы для ключей. ,

Затем можно использовать сопоставленный тип для извлечения типа ключа карты (keyof возвращает члены типа, не имеет ничего общего с ключом карты)

const svgAttributeToCssStyle = new Map([
  ["alignment-baseline", "alignmentBaseline"],
  ["baseline-shift", "baselineShift"],
  ["clip", "clip"],
  ["clip-path", "clipPath"],
  // ...
] as const);

type MapKeyType<T extends Map<any, any>> = T extends Map<infer K, any> ? K : never;
export function getPresentationAttribute(attribute: MapKeyType<typeof svgAttributeToCssStyle>) {

}

getPresentationAttribute("clip-path")
getPresentationAttribute("clipPath") // errr

Playground Link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...