我正在try 创建一个可以处理两个互斥返回类型的函数.我对打字的工作原理有什么误解?
type SuccessResponse<T> = { data: T; error: null };
type ErrorResponse<E> = { data: null; error: NonNullable<E> };
type Command<T, E> = () => ErrorResponse<E> | SuccessResponse<T>;
const myFunc = <T, E>(c: Command<T, E>): T => {
const result = c();
if (result.error !== null) throw result.error;
return result.data;
}
我在返回时收到以下错误:
Type 'T | null' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'T | null'.(2322)
我不能只测试if (result.data)
,因为T
是null
是可以接受的.
下面是一个更长的示例,它解释了想要错误类型的动机:这样实用程序就可以断言并存储它以供以后使用.(假设makeRefreshable
或myCommand
都不在我的控制之下)
type SuccessResponse<T> = { data: T; error: null };
type ErrorResponse<E> = { data: null; error: NonNullable<E> };
type Command<T, E> = () => Promise<ErrorResponse<E> | SuccessResponse<T>>;
const myCommand = async () => {
if (Math.random() < .1) return {data: null, error: new Error('Random error')};
return await { data: Math.random(), error: null};
}
const getCommandResult = async <T, E>(c: Command<T, E>): Promise<T> => {
const result = await c();
if (result.error !== null) throw result.error;
return result.data;
}
const makeRefreshable = <T, E>(f: () => Promise<T>) => {
const result: {
data: T | null;
error: E | null;
run: () => void;
} = {
data: null,
error: null,
run: () => {},
}
result.run = async () => {
try {
result.data = await f();
} catch (err) {
result.data = null;
result.error = err as E;
}
}
return result;
}
const main = async () => {
const result = makeRefreshable<number, Error>(() => getCommandResult(myCommand));
await result.run();
if (result.data) console.log(result.data);
if (result.error) console.log(result.error.message);
await result.run();
if (result.data) console.log(result.data);
if (result.error) console.log(result.error.message);
}
main();