简体   繁体   English

如何根据Typescript中的字符串参数定义函数的参数类型?

[英]How to define a function's argument type dependent on string argument in Typescript?

I have a existing function in Javascript code for which I'm trying to write a type definition file in order to have strict type checking.我在 Javascript 代码中有一个现有函数,我正在尝试为其编写类型定义文件以进行严格的类型检查。 It is used like this:它是这样使用的:

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

The project uses custom html elements.该项目使用自定义 html 元素。 The first argument is a string with the tag and as you can see the type of the second argument is dependent on the string tag, as it should be an attribute-to-value map consistent with what the tag expects.第一个参数是一个带有标签的字符串,正如你所看到的,第二个参数的类型取决于字符串标签,因为它应该是一个与标签期望一致的属性到值映射。

I'm trying something like this but it does not work.我正在尝试这样的事情,但它不起作用。

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

It complains about the unused "T" argument and does not complain about the wrong string parameter with the numberTag.它会抱怨未使用的“T”参数,并且不会抱怨 numberTag 的字符串参数错误。 If I use an existing generic type like Array<T> instead of Tag<T> , doStuff correctly constraints the second argument.如果我使用现有的泛型类型,如Array<T>而不是Tag<T> , doStuff 会正确约束第二个参数。

I'm trying to maintain the existing api (the string-typed tag), but could consider changing it.我正在尝试维护现有的 api(字符串类型标签),但可以考虑更改它。

Thanks.谢谢。

The only way I can think of doing this with is 'string literal types', and conditional types, so you'll have to manually spell out all those type definitions.我能想到的唯一方法是“字符串文字类型”和条件类型,因此您必须手动拼出所有这些类型定义。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM