打字稿不推断表达式签名匹配

时间:2019-07-09 00:27:27

标签: typescript

我一直在处理Typescript中的一些通用代数数据类型(v3.5.2应该是最新的),并且似乎在检测似乎应该能够弄清楚的函数上的签名匹配时遇到了麻烦:

  type Success<T> = {          
    tag: 'success';            
    value: T;
    fbind<R, E>(func: (value: T) => Result<R, E>) : Result<R, E>;
  } 

  type Failure<E> = {          
    tag: 'failure';
    error: E;
    fbind<T>(_func: (value: T) => Failure<E>) : Failure<E>;
  }

  type Result<T, E> = Success<T> | Failure<E>;

  function success<T>(value: T) : Success<T> {
    return {
      tag: 'success',
      value,
      fbind<R, E>(func: (value: T) => Result<R, E>): Result<R, E> {
        return func(this.value);
      },
    };
  }

  function failure<E>(error: E) : Failure<E> {
    return {
      tag: 'failure',
      error,
      fbind<T>(_func: (value: T) => Failure<E>) : Failure<E> {
        return this;
      },
    };
  }

  type ValidationError = string;

  function parseDate(value: string) : Result<Date, ValidationError> { 
    // simple example to show issue 
    return success(new Date(value));
  }

  function logDate(date: Date) : Result<Date, ValidationError> {
    console.log('Date: ', date);
    return success(date);
  }

  parseDate('1-1-2019').fbind(logDate);

在对.fbind的{​​{1}}调用中,它输出以下错误:

logDate

我看不到的地方有错误吗?还是有一种方法可以为类型系统提供一些帮助,以便它可以解决?

更新

使用以下代码:

Cannot invoke an expression whose type lacks a call signature. Type '(<R, E>(func: (value: Date) => Result<R, E>) => Result<R, E>) | (<T, R>(_func: (value: T) => Result<R, string>) => Result<R, string>)' has no compatible call signatures.

在对type Success<T> = { tag: 'success'; value: T; fbind<R, E>(func: (value: T) => Result<R, E>) : Result<R, E>; } type Failure<E> = { tag: 'failure'; error: E; fbind<T, R>(_func: (value: T) => Result<R, E>) : Result<R, E>; } type Result<T, E> = Success<T> | Failure<E>; function success<T>(value: T) : Success<T> { return { tag: 'success', value, fbind<R, E>(func: (value: T) => Result<R, E>): Result<R, E> { return func(this.value); }, }; } function failure<E>(error: E) : Failure<E> { return { tag: 'failure', error, fbind<T, R>(_func: (value: T) => Result<R, E>) : Result<R, E> { return this; }, }; } type ValidationError = string; function parseDate(value: string) : Result<Date, ValidationError> { // simple example to show issue return success(new Date()) } function logDate(date: Date) : Result<Date, ValidationError> { console.log('Date: ', date); return success(date); } parseDate('1-1-2019').fbind(logDate); 的{​​{1}}调用中,它仍然输出以下错误:

.fbind

在打字稿存储库上提交问题后,看来打字稿当前不支持调用3.5.3及更低版本(https://github.com/microsoft/TypeScript/issues/32314)中的多个通用函数签名的并集。

1 个答案:

答案 0 :(得分:1)

如果您按以下方式分解实现,并使其更加详细

add-content

您会得到更具体的错误

const result = parseDate('1-1-2019');
if (result.tag === 'success') {
  result.fbind(logDate);
} else if (result.tag === 'failure') {
  result.fbind(logDate);
}

因此,由于Argument of type '(date: Date) => Result<Date, string>' is not assignable to parameter of type '(value: Date) => Failure<string>'. Type 'Result<Date, string>' is not assignable to type 'Failure<string>'. Property 'error' is missing in type 'Success<Date>' but required in type 'Failure<string>' 返回的是Success或Failure,并且它们的parseDate的两个实现均采用不同的回调,因此在某些情况下,如果fbind返回Failure,则我们尝试通过parseData(输出成功/失败)到失败的logDate中,它仅接受返回fbind的回调,因此打字稿会引发错误。