【问题标题】:null cannot be assigned to typenull 不能分配给类型
【发布时间】:2019-02-25 02:13:58
【问题描述】:

在我的 TypeScript 项目中,我创建了一个自定义类(顺便说一下,受 Rust 的 Result<T, E> 启发),它看起来像这样:

export class Result<T, E extends Error = Error>
{
    public errors: E[] = [];
    public result: T | null = null;

    public static ok<T, E extends Error>(result: T): Result<T, E>
    {
        return new Result(result, [] as E[]);
    }

    public static err<T, E extends Error>(...errors: E[]): Result<T, E>
    {
        return new Result<T, E>(null as unknown as T, errors);
    }

    public static apiErr<T>(...errors: ApiErrorKind[]): Result<T, ApiError>
    {
        return new Result<T, ApiError>(null as unknown as T, errors.map(e => new ApiError(e)));
    }

    private constructor(result: T | null, errors: E[])
    {
        this.result = result;
        this.errors = errors;
    }

    public and<T2, E2 extends Error = E>(f: (x: T) => Result<T2, E2>): Result<T2, E | E2>
    {
        if (this.isErr)
            return Result.err(...this.errors);

        let errors: (E | E2)[] = this.errors;

        try
        {
            return f(this.result as T);
        }
        catch (e)
        {
            errors.push(e as E2);
        }

        return Result.err(...errors);
    }

    // irrelevant methods omitted for brevity

    public then<T2, E2 extends Error = E>(f: (x: T | null) => T2): Result<T2, E | E2>
    {
        if (this.isErr)
            return Result.err(...this.errors);

        let errors: (E | E2)[] = this.errors;

        try
        {
            return Result.ok(f(this.result));
        }
        catch (e)
        {
            errors.push(e as E2);
        }

        return Result.err(...errors);
    }
}

但是,每当我尝试使用它时,我总是收到关于 null 转换的神秘错误,尽管没有看到任何 null

export async function createUser(input: UserInput, organization: string): Promise<Result<User, ApiError>>
{
    const validation = validateUser(input); // returns Result<boolean, ApiError>

    if (validation.isErr)
        return Result.err<User, ApiError>(... validation.errors); // Error on this line
}

TS2322 输入“用户 | null' 不可分配给类型 'Result'。类型“null”不能分配给类型“Result”。

为什么会这样?

【问题讨论】:

  • 你使用的是什么版本的 TypeScript?
  • 我在本地机器上运行了您的代码示例,但没有看到您遇到的错误。
  • @ShaunLuttin 3.3.3333

标签: typescript


【解决方案1】:

您可以在 tsconfig.json 的 compilerOptions 中设置 "strictNullChecks": false。

更多详情请看this答案和this链接。

【讨论】:

    【解决方案2】:

    问题是由于我在Result&lt;T, E&gt; 类型上放置了then 方法引起的。当我尝试从 async 方法返回类型时,这会产生冲突,因为 TypeScript 一直假设我的 Result&lt;T, E&gt; 是伪Promise 并试图通过调用 .then() 来解开它。

    TypeScript 对于这种情况通常有一个更清晰的错误:

    TS1058 异步函数的返回类型必须是有效的承诺,或者不能包含可调用的“then”成员。

    但是一旦方法接受一个函数作为参数,它就会变得更加混乱,因为这就是Promise 的实际方法签名的样子,而且它与所涉及的泛型更加混淆。

    【讨论】:

      猜你喜欢
      • 2022-01-27
      • 1970-01-01
      • 2021-06-08
      • 2021-06-12
      • 1970-01-01
      • 2018-04-05
      • 2021-09-30
      • 2021-06-28
      • 1970-01-01
      相关资源
      最近更新 更多