Typescript字符串驱动打字

Typescript字符串驱动打字,typescript,typescript-typings,Typescript,Typescript Typings,是否可以通过以下行为声明Typescript函数的类型: declare const fun: HowToTypeThis export const string_or_number_fun = fun< 'num', number, 'str', string >() 我的尝试让我想到: interface HowToTypeThis { <Name1 extends string, Type1, Name2 extends string, T

是否可以通过以下行为声明Typescript函数的类型:

declare const fun: HowToTypeThis


export const string_or_number_fun = fun<
  'num', number,
  'str', string
  >()
我的尝试让我想到:

interface HowToTypeThis {

  <Name1 extends string, Type1,
    Name2 extends string, Type2>(): <N = Name1 | Name2>(_: N, __: N extends Name1
      ? Type1
      : N extends Name2
      ? Type2
      : never): any

}
接口如何键入此{
():(:N,:N扩展名称1
?类型1
:N扩展名称2
?类型2
:从来没有
}
TS编译器将字符串或编号报告为以下类型:

 const string_or_number_fun: 
 <N = "num" | "str">(_: N, __: N extends "num" ? number : N extends "str" ? string : never) => any
const string\u或\u number\u fun:
(:N,:N扩展“num”?number:N扩展“str”?string:never)=>any
看起来还可以

但我得到:
类型为“”的参数不能分配给类型为“从不”的参数。[2345]

[ts]类型为“12”的参数不能分配给类型为“从不”的参数。[2345]


它也不能防止键入意外的字符串作为第一个参数

您可以通过首先声明自定义类型名到它所表示的类型的映射,然后将其作为函数声明的一部分来实现所需的功能。比如:

interface TypeNameToType {
    num: number;
    str: string;
}

function fun<T extends keyof TypeNameToType>(type: T, value: TypeNameToType[T])
{
    return value;
}
接口类型名称类型{
num:数字;
str:字符串;
}
函数fun(类型:T,值:TypeNameToType[T])
{
返回值;
}

现在,如果您尝试调用
fun('num','thisisString')
Typescript会因为您使用了
'num'
而生气,但第二个参数不是数字。

必须对
N
type参数设置一个约束,使其成为
string
,从而导致
从不
来自条件类型

N extensed Name1 | Name2
是代码中唯一缺少的部分:

interface HowToTypeThis {

  <Name1 extends string, Type1,
    Name2 extends string, Type2>(): <N extends Name1 | Name2 = Name1 | Name2>(_: N, __: N extends Name1
      ? Type1
      : N extends Name2
      ? Type2
      : never) => any

}
接口如何键入此{
():(:N,:N扩展名称1
?类型1
:N扩展名称2
?类型2
:从不)=>任何
}

哇,奇怪我为什么不试试看!:)1问:我现在尝试了
而不是
,似乎也没问题,对此有什么考虑吗?似乎
N
的默认值
=Name1 | Name2
在这里是不必要的;如果调用站点未提供类型参数的回退值,则通常使用该参数。如果编译器可以从参数值推断出
N
的正确类型,则不需要使用默认值。不错,这个解决方案不符合我的构造,不过,看起来可以引入映射接口,使其更整洁
interface HowToTypeThis {

  <Name1 extends string, Type1,
    Name2 extends string, Type2>(): <N extends Name1 | Name2 = Name1 | Name2>(_: N, __: N extends Name1
      ? Type1
      : N extends Name2
      ? Type2
      : never) => any

}