打字稿定义-嵌套函数 [英] Typescript Definitions - nested functions
问题描述
如下所示,我们有:
- 将多个任务组合在一起的功能
r
- 和返回
when(cb).map(cb)
形状的函数
o
传递给when
或map
的每个回调都应始终使用以下3
参数:S, A, C
其中S
和C
在r
中定义,而A
在o
中定义
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
的回调不是类型安全的:参数S
和C
丢失.
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) ofFn<S, any, C>
values, so the fact that the second task'sA
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}
.
仅具有所需的泛型类型,并且尽可能接近所需的推理位置.我已经将S
和C
移到了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()
中的S
和C
的值的上下文键入.编译器甚至可能甚至没有尝试执行此操作,因为推断必须在多个级别的函数调用中进行.解决该问题的唯一方法似乎是通过注释传递给o().when()
的回调的s
和c
参数或通过调用o().when<2,7>()
来重新指定S
和C
.
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屋!