在我的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'类型。
为什么会这样?
答案 0 :(得分:1)
该问题是由于我在then
类型上放置了Result<T, E>
方法而引起的。当我尝试从async
方法返回类型时,这造成了冲突,因为TypeScript一直假设我的Result<T, E>
是伪Promise
并尝试通过调用{{1}来拆开它}。
对于这种情况,TypeScript通常有一个更清晰的错误:
TS1058 异步函数的返回类型必须是有效的Promise或不能包含可调用的'then'成员。
但是一旦该方法接受一个函数作为参数,它就会变得更加混乱,因为这是实际的.then()
的方法签名的样子,并且与所涉及的泛型更加混淆。
答案 1 :(得分:0)