Как определить тип аргумента функции в зависимости от строкового аргумента в Typescript?

У меня есть существующая функция в коде Javascript, для которой я пытаюсь написать файл определения типа для строгой проверки типов. Используется так:

createElement("a", {href: "www.example.com"});

В проекте используются пользовательские элементы HTML. Первый аргумент - это строка с тегом, и, как вы можете видеть, тип второго аргумента зависит от строкового тега, поскольку он должен быть картой атрибута-значения, соответствующей тому, что ожидает тег.

Я пытаюсь что-то вроде этого, но это не работает.

type Tag<T> = string;
const stringTag: Tag<string> = "IamString";
const numberTag: Tag<number> = "IamNumber";

function doStuff<T>(
    tag: Tag<T>,
    content: T
): void {
    console.log(tag, content);
}

doStuff(stringTag, "IshouldBeString");
doStuff(numberTag, "IshouldBeNumber"); // Should be WRONG
doStuff(numberTag, 10); // CORRECT

Он жалуется на неиспользуемый аргумент "T" и не жалуется на неправильный строковый параметр с numberTag. Если я использую существующий универсальный тип, такой как Array<T> вместо Tag<T> , doStuff правильно ограничивает второй аргумент.

Я пытаюсь сохранить существующий API (строковый тег), но мог бы изменить его.

Спасибо.

Всего 1 ответ


Единственный способ, которым я могу думать об этом, - это «строковые литеральные типы» и условные типы, так что вам придется вручную прописать все эти определения типов.

type TagType = "a" | "button";
type Tag<T extends TagType> =
    T extends "a" ? AType :
    T extends "button" ? ButtonType : never;

interface AType {
    href: string;
}

interface ButtonType {
    onClick: () => void
}

function doStuff<T extends TagType>(tag: T, content: Tag<T>) {
    console.log(tag, content)
}

doStuff("a", { href: "" }); // CORRECT
doStuff("button", { href: "" }); // WRONG
doStuff("button", { onClick: () => {} }); // CORRECT

Есть идеи?

10000