Javascript 类型脚本定义-嵌套函数

Javascript 类型脚本定义-嵌套函数,javascript,typescript,typescript-typings,typescript-types,typescript-definitions,Javascript,Typescript,Typescript Typings,Typescript Types,Typescript Definitions,如下所列,假设我们有: 将多个任务组合在一起的函数r 还有一个函数o,它返回的形状类似于when(cb).map(cb) 当或map时传递给的每个回调应始终采用3个参数:S、A、C,其中S和C在r中定义,A在o中定义 这里有一个指向的链接,它也显示了我得到的错误 我的问题是:如何获得类型安全声明? 类型任务= 正如您所看到的,当不是类型安全时提供给的回调:参数S和C丢失了嗯,除此之外,您似乎想要一些该语言没有提供的。以下是我建议键入内容的方式: type Fn<S, A, C> =

如下所列,假设我们有:

  • 将多个任务组合在一起的函数
    r
  • 还有一个函数
    o
    ,它返回的形状类似于
    when(cb).map(cb)
  • map
    时传递给
    的每个回调应始终采用
    3个
    参数:
    S、A、C
    ,其中
    S
    C
    r
    中定义,
    A
    o
    中定义

    这里有一个指向的链接,它也显示了我得到的错误

    我的问题是:如何获得类型安全声明?

    类型任务=


    正如您所看到的,
    不是类型安全时提供给
    的回调参数
    S
    C
    丢失了

    嗯,除此之外,您似乎想要一些该语言没有提供的。以下是我建议键入内容的方式:

    type Fn<S, A, C> = (s: S, a: A, c: C) => any;
    
    // allow tasks to be an array of Fn<S, any, C> 
    const r = <S, C>() => ({
      tasks: <FF extends Fn<S, any, C>[]>(...tasks: FF) => null,
    });
    // it is concerning that S and C must be explicitly specified
    // when calling r(); not sure how you will hook that up to runtime
    
    // only make types generic if they need to be, 
    // and declare close to their uses if you want them to be inferred
    const o = <T>(type: T) => ({
      when: <S, C>(fp: Fn<S, { prop: T }, C>) => ({
        map: (fn: Fn<S, { prop: T }, C>) => (s: S, a: { prop: T }, c: C): any =>
          fp(s, a, c) ? fn(s, a, c) : s,
      }),
    });
    
    const result = r<2, 7>().tasks(
      o(44) // expect: db(2, 44, 7)
        // you need to annotate the s and c parameters in when().
        // The compiler does not try to infer S and C in o(44).when() contextually 
        // from the contextual parameter type of r<2.7>().tasks().
        .when((s: 2, a, c: 7) => s + a.prop + c)
        .map((s, a, c) => s + a.prop + c),
    
      o(78) // expect: db(2, 78, 7)        
        // alternatively you can specify S and C manually:
        .when<2, 7>((s, a, c) => s + a.prop + c)
        .map((s, a, c) => s + a.prop + c),
      // etc...
    );
    
    type Fn=(s:s,a:a,c:c)=>any;
    //允许任务成为Fn的数组
    常数r=()=>({
    任务:(…任务:FF)=>null,
    });
    //这涉及到必须明确指定S和C
    //调用r()时;不确定如何将其连接到运行时
    //仅在需要时使类型成为泛型,
    //如果你想推断出它们的用途,就声明它们接近它们的用途
    常数o=(类型:T)=>({
    时间:(fp:Fn)=>({
    map:(fn:fn)=>(s:s,a:{prop:T},c:c):any=>
    fp(s,a,c)?fn(s,a,c):s,
    }),
    });
    const result=r()。任务(
    o(44)//expect:db(2,44,7)
    //您需要在when()中注释s和c参数。
    //编译器不会尝试在o(44).when()上下文中推断S和C
    //来自上下文参数类型r().tasks()。
    .当((s:2,a,c:7)=>s+a.prop+c)
    .map((s,a,c)=>s+a.prop+c),
    o(78)//expect:db(2,78,7)
    //或者,您可以手动指定S和C:
    .当((s,a,c)=>s+a.prop+c)
    .map((s,a,c)=>s+a.prop+c),
    //等等。。。
    );
    
    自从我写这篇文章以来,你已经更改了你的定义,所以下面的内容可能与你发布的内容不完全匹配。简言之:

    • 使
      r().tasks()
      获取一个
      Fn
      值的数组(可能是a),这样第二个任务的
      a
      与第一个任务的
      不同这一事实就不会导致错误

    • 没有泛型
      t
      ,也没有泛型
      a={prop:t}
      。我猜
      A
      并不意味着独立于
      T
      ,您正试图使用A来表示某种赋值,但实际上并不是这样。相反,只需使用
      T
      ,然后将
      A
      的所有实例替换为
      {prop:T}

    • 只有尽可能多的泛型类型,并且尽可能靠近所需的推理位置。我已将
      S
      C
      移动到
      o()

    • 最后,从
      r().tasks()
      的参数到
      S
      C
      o().when()的上下文输入不会发生。编译器可能甚至没有尝试这样做,因为推理必须跨多个级别的函数调用进行。处理这个问题的唯一方法似乎是重新指定
      S
      C
      ,或者通过注释传递给
      o().when()
      的回调的
      S
      C
      参数,或者通过调用
      o().when()


    希望这能帮你指明正确的方向。祝你好运

    您好@jcalz,感谢您指出类型分配。之所以在
    r
    中定义
    S
    C
    ,是因为
    r
    表示一些已经存在的东西,它们将始终调用具有相同
    S
    C
    的所有任务:任务无法控制它。我真的不明白为什么
    map
    的类型正确,而
    when
    的类型不正确……因为
    when()
    是一个泛型函数(它有
    S
    C
    作为类型参数),返回一个带有非泛型
    map()
    函数的对象。调用
    o(44).when()
    时,返回对象的
    map()
    已经没有未指定的泛型类型参数。。已知其
    fn
    参数的类型为
    (s:2,a:{prop:number},c:7)=>任意