打字稿:为什么它试图针对所有函数重载调整参数类型?

我正在寻找一个打字稿大师来帮助我解决这个问题。我正在尝试在 Typescript 中实现一些 monadic 行为。我有一个可以采用 4 种不同形状的数据类型。我希望能够拥有像mapand这样的基本一元函数flatMap。


我一直在努力让打字稿编译器对我的类型感到满意,我尝试了多种方法(使用类、抽象类、简单类型等),但这是我想到的最好的方法。


export namespace Data {

  export type Initial<T,E> = { kind: 'initial' }

  export type Loading<T,E> = { kind: 'loading' }

  export type Loaded<T,E> = { kind: 'loaded'; value: T }

  export type Failed<T, E> = { kind: 'failed'; error?: E }

  export type Data<T,E = any> = Failed<T,E> | Loaded<T,E> | Loading<T,E> | Initial<T,E>

  type Kind = Data<any,any>['kind']


  // Instantiations

  export function loadingOf<T=any,E=any>():Loading<T,E> { return {kind: 'loading'}}

  export function initialOf<T=any,E=any>():Initial<T,E> { return {kind: 'initial'}}

  export function loadedOf<T=any,E=any>(value: T):Loaded<T,E> { return {kind: 'loaded', value}}

  export function failedOf<T=any,E=any>(error?: E):Failed<T,E> { return {kind: 'failed', error}}


  // Type guards

  export function isFailed<T,E>( data: Data<T,E>): data is Failed<T,E> { return data.kind === 'failed'}

  export function isLoaded<T,E>( data: Data<T,E>): data is Loaded<T,E> { return data.kind === 'loaded'}

  export function isInitial<T,E>( data: Data<T,E>): data is Initial<T,E> { return data.kind === 'initial'}

  export function isLoading<T,E>( data: Data<T,E>): data is Loading<T,E> { return data.kind === 'loading'}

这当然是不完整的,因为 typescript 对 map 功能不满意

如果我交换重载的顺序,它只会将错误代码的最后一行更改initial为其他内容。


我不明白为什么它对这些类型不满意。不完全Data<T,E>合适?为什么要尝试拟合参数类型以匹配所有可能的重载的参数类型?


如果我删除带有子类型的签名并只保留最通用的签名,那么它就会停止抱怨,但它会使类型变得松散。任何子类型都将被强制为其松散的类型Data<T,E>,这是我不想要的。


慕的地8271018
浏览 99回答 1
1回答

冉冉说

实现签名不参与重载决议,如本页最后一段所述。如果您需要 的通用版本map,具有通用签名的实现是不够的,您必须显式添加它,作为单独的仅声明重载:export function map<T,U,E>(fn: (t: T) => U, data: Data<T,E>): Data<U, E>;export function map<T,U,E>(fn: (t: T) => U, data: Data<T,E>) {&nbsp; &nbsp; // implementation here....}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript