gpt4 book ai didi

typescript - 为什么命名函数的处理方式与循环依赖中的箭头函数不同?

转载 作者:行者123 更新时间:2023-12-04 13:26:34 25 4
gpt4 key购买 nike

我正在尝试在 TypeScript 中推出我自己的依赖注入(inject)机制,但我遇到了一个有趣的问题。在声明我的依赖项时,我必须使用命名函数而不是箭头函数(这通常是我的默认值),否则我会收到循环声明错误。
下面是组成我的依赖解析器的类型集:

type CollectionTemplate = {
[key: string]: (...args: any) => any
}

type RegistryTemplate = {
[key: string]: CollectionTemplate
}

type RegistryCollection<R extends RegistryTemplate> = keyof R

type CollectionEntry<C extends CollectionTemplate> = keyof C

type BaseRegistry<R extends RegistryTemplate> = R

type BaseContext<R extends RegistryTemplate> = {
[C in RegistryCollection<R>]: {
[E in CollectionEntry<R[C]>]: ReturnType<R[C][E]>
}
}

type BaseUseDep<R extends RegistryTemplate> =
<C extends RegistryCollection<R>, E extends CollectionEntry<R[C]>>
(collection: C, entry: E) => BaseContext<R>[C][E]
现在,当我使用命名函数时,这一切正常:
type DepRegistry = BaseRegistry<typeof registry>
type DepContext = BaseContext<DepRegistry>
type UseDep = BaseUseDep<DepRegistry>

function greet(deps: UseDep)
{
return (name: string) =>
{
const console = deps('system', 'console')
console.log(name)
}
}

function printGreeting(deps: UseDep)
{
return () =>
{
const greet = deps('social', 'greet')
greet('John')
}
}

const registry = {
system: {
console: () => console,
},
social: {
greet,
printGreeting,
}
}
但是,如果我使用箭头函数而不是命名函数声明这些函数,则会出现以下错误:
Type alias 'DepRegistry' circularly references itself. ts(2456)
Type alias 'UseDep' circularly references itself. ts(2456)
为什么是这样?仅仅是因为我将一个函数分配给一个变量而不是声明一个显式函数吗?
编辑:这是带有 named functionsarrow functions 的游乐场。

最佳答案

以下答案部分解释了这个问题;这意味着是一个评论
我认为,命名函数和箭头函数之间差异背后的原因可能是 lazy vs eager类型签名的解析。
Anders Hejlsberg compared interface vs type resolution in this GitHub comment :

The trick is to make the recursive back references within interface types. This works because resolution of interface base types and interface members is deferred, whereas resolution of type aliases is performed eagerly.


签名 function可以用 interface { (...params: Params): Return } 指定因此 Typescript 编译器使用惰性解析策略,并且允许递归定义。
我不知道为什么箭头函数被区别对待,但似乎他们的类型签名被急切地评估。

我经常遵循类似的依赖项注册/注入(inject)模式,并且之前遇到过这个问题。从来没有想过用常规函数替换箭头。很高兴知道这是一种可能性。您也可以首先考虑避免循环依赖。
这个问题本身非常违反直觉,同时也非常有趣。

关于typescript - 为什么命名函数的处理方式与循环依赖中的箭头函数不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68104491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com