Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Typescript:为什么它试图针对所有函数重载调整参数类型?_Javascript_Typescript_Types_Functional Programming_Monads - Fatal编程技术网

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

Javascript Typescript:为什么它试图针对所有函数重载调整参数类型?,javascript,typescript,types,functional-programming,monads,Javascript,Typescript,Types,Functional Programming,Monads,我正在寻找一位打字大师来帮助我。我试图在Typescript中实现一些一元行为。我有一个数据类型,可以有4种不同的形状。我希望能够拥有基本的一元函数,如map和flatMap 我一直在努力使typescript编译器对我的类型感到满意,我尝试了多种方法(使用类、抽象类、简单类型等),但这是我想到的最好的方法 export namespace Data { export type Initial<T,E> = { kind: 'initial' } export type Lo

我正在寻找一位打字大师来帮助我。我试图在Typescript中实现一些一元行为。我有一个数据类型,可以有4种不同的形状。我希望能够拥有基本的一元函数,如
map
flatMap

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

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'}

  // Map
  export function map<T,U,E>(fn: (t: T) => U, data: Loaded<T,E>): Loaded<U,E>;
  export function map<T,U,E>(fn: (t: T) => U, data: Failed<T,E>): Failed<U,E>;
  export function map<T,U,E>(fn: (t: T) => U, data: Loading<T,E>): Loading<U,E>;
  export function map<T,U,E>(fn: (t: T) => U, data: Initial<T,E>): Initial<U,E>;
  export function map<T,U,E>(fn: (t: T) => U, data: Data<T,E>) {
    if(isLoaded(data)) {
      return loadedOf(fn(data.value))
    }
    return data
  }
}

const a = Data.map(x => x, Data.loadedOf('hi'))
const b = Data.map(x => x, Data.loadingOf<string>())
const c = Data.map(x => x, Data.initialOf<string>())
const d = Data.map(x => x, Data.failedOf<string>())
const datas:Data.Data<string>[] = [a,b,c,d]
datas.map(data => Data.map(x=>x, data))
如果我交换重载的顺序,它只会将错误代码的最后一行从
initial
更改为其他内容

我不明白为什么它对这些类型不满意。
数据是否完全合适?为什么要尝试使参数类型与所有可能重载的参数类型相匹配


如果我删除带有子类型的签名,只保留最通用的一个,那么它将停止抱怨,但会使类型松散。任何子类型都将被强制为较松散的类型
Data
,这是我不想要的。

实现签名不参与重载解决,如上一段所述

如果您需要通用版本的
映射
,拥有具有通用签名的实现是不够的,您必须显式地添加它,因为单独的声明只会重载:

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>) {
    // implementation here....
}
导出功能图(fn:(t:t)=>U,数据:数据):数据;
导出功能图(fn:(t:t)=>U,数据:数据){
//在这里实现。。。。
}

如上一段所述,实现签名不参与过载解决

如果您需要通用版本的
映射
,拥有具有通用签名的实现是不够的,您必须显式地添加它,因为单独的声明只会重载:

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>) {
    // implementation here....
}
导出功能图(fn:(t:t)=>U,数据:数据):数据;
导出功能图(fn:(t:t)=>U,数据:数据){
//在这里实现。。。。
}