无法将null分配给type

时间:2019-02-24 02:28:43

标签: typescript

在我的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'类型。

为什么会这样?

2 个答案:

答案 0 :(得分:1)

该问题是由于我在then类型上放置了Result<T, E>方法而引起的。当我尝试从async方法返回类型时,这造成了冲突,因为TypeScript一直假设我的Result<T, E>是伪Promise并尝试通过调用{{1}来拆开它}。

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

  

TS1058 异步函数的返回类型必须是有效的Promise或不能包含可调用的'then'成员。

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

答案 1 :(得分:0)

您可以在tsconfig.json的editorOptions中设置“ strictNullChecks”:false。

有关更多详细信息,请参见this答案和this链接。