打字稿字符串驱动的打字

时间:2018-11-30 22:13:02

标签: typescript typescript-typings

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

declare const fun: HowToTypeThis


export const string_or_number_fun = fun<
  'num', number,
  'str', string
  >()

string_or_number_fun应该接受 要么
string_or_number_fun('str', string)

string_or_number_fun('num', number)

string_or_number_fun('str', '') 
string_or_number_fun('num', 12) 

我的尝试使我想到了这一点:

interface HowToTypeThis {

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

}

TS编译器报告类型为string_or_number_fun的

 const string_or_number_fun: 
 <N = "num" | "str">(_: N, __: N extends "num" ? number : N extends "str" ? string : never) => any

看起来还可以

但我得到了:
[ts] Argument of type '""' is not assignable to parameter of type 'never'. [2345]

[ts] Argument of type '12' is not assignable to parameter of type 'never'. [2345]

并且也不防止输入意外的字符串作为第一个参数

2 个答案:

答案 0 :(得分:2)

首先声明自定义类型名称到其表示的类型的映射,然后将其用作函数声明的一部分,即可实现所需的功能。像这样:

fun('num', 'thisisastring');

现在,如果您尝试调用'num',则打字稿会因为使用flatlistHeader = () => { if (this.state.isRewarded) { return ( <View> <Text style={{ color: '#fff' }}>Is rewarded</Text> </View> ); } else { return ( <View> <TouchableOpacity onPress={() => this.showRewareded()} > <Text style={{ color: '#fff' }}>Reward me</Text> </TouchableOpacity> </View> ) } } 而发疯,但第二个参数不是数字。

答案 1 :(得分:1)

N类型参数otherwise it will be widenedstring必须受到约束,导致never来自条件类型。

N extends 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

}