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)=>任意
。