打字稿定义-嵌套函数 [英] Typescript Definitions - nested functions

查看:104
本文介绍了打字稿定义-嵌套函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如下所示,我们有:

  1. 将多个任务组合在一起的功能r
  2. 和返回when(cb).map(cb)
  3. 形状的函数o

传递给whenmap的每个回调都应始终使用以下3参数:S, A, C其中SCr中定义,而Ao中定义

every callback passed to when or map should always take these 3 arguments: S, A, C where S and C are defined in r and A is defined in o.

这是

here is a link to the typescript playground which also shows the error I am getting.

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

type Task<S, A, C> = <AA extends A>(s: S, a: AA, c: C) => any;
type Fn<S, A, C> = (s: S, a: A, c: C) => any;

const r = <S, C>() => ({
  tasks: (...tasks: Task<S, any, C>[]) => null,
});

const o = <T, A = { prop: T }>(type: T) => ({
  when: <S, C>(fp: Fn<S, A, C>) => ({
    map: <SS extends S, CC extends C>(fn: Fn<SS, A, CC>): Task<SS, A, CC> => (
      (s: SS, a: A, c: CC): any => (
        fp(s, a, c) ? fn(s, a, c) : s
      )
    ),
  }),
});

const result = r<2, 7>().tasks(
  o(44) // expect: cb(2, 44, 7)
    .when((s, a, c) => s + a.prop + c)
    .map((s, a, c) => s + a.prop + c),

  o(78) // expect: cb(2, 78, 7)
    .when((s, a, c) => s + a.prop + c)
    .map((s, a, c) => s + a.prop + c),

  // etc...
  // callback provided to `.map` is typesafe,
  // callback provided to `.when` is not,
);

如您所见,提供给when的回调不是类型安全的:参数SC丢失.

As you can see, the callback provided to when is not typesafe: Params S and C are lost.

推荐答案

嗯,除了其他问题外,您似乎还需要

Hmm, among other problems, it looks like you want some contextual type inference that the language doesn't provide for. Here is how I would recommend typing things:

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...
);

自从我从事此工作以来,您已经更改了定义,因此以下内容可能与您发布的内容不完全匹配.简而言之:

You've changed your definitions since I worked on this, so the following might not match up exactly with what you posted. In short:

  • Make r().tasks() take an array (possibly a tuple) of Fn<S, any, C> values, so the fact that the second task's A is not the same as the first won't cause an error.

既没有通用T,也没有通用A = {prop: T}.我猜A并不意味着要独立于T,而您正在尝试使用

Don't have a generic T and also a generic A = {prop: T}. I'm guessing A is not meant to be independent from T and you are trying to use a default type parameter to represent some kind of assignment, but it doesn't really work that way. Instead, just use T and then replace all instances of A with {prop: T}.

仅具有所需的泛型类型,并且尽可能接近所需的推理位置.我已经将SC移到了o().when.

Only have as many generic types as you need and as close to the desired inference place as possible. I've moved S and C to o().when.

最后,不会发生从r<2.7>().tasks()的参数到o().when()中的SC的值的上下文键入.编译器甚至可能甚至没有尝试执行此操作,因为推断必须在多个级别的函数调用中进行.解决该问题的唯一方法似乎是通过注释传递给o().when()的回调的sc参数或通过调用o().when<2,7>()来重新指定SC.

Finally, contextual typing from the parameter of r<2.7>().tasks() to the values of S and C in o().when() does not occur. The compiler probably doesn't even try to do it, since the inference would have to happen across multiple levels of function call. The only way to deal with that seems to be to re-specify S and C, either by annotating the s and c parameters of the callback passed to o().when(), or by calling o().when<2,7>().

希望能为您指明正确的方向.祝你好运!

Hope that helps point you in the right direction. Good luck!

这篇关于打字稿定义-嵌套函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆