我有这种类型,我的 value
属性是“可选的”(如果 T
不是 undefined
)
type AsyncState<T = undefined> = {
value?: T;
loading: boolean;
error: { reason: string } | null;
}
现在我需要以某种方式创建依赖于
AsyncState
的新对象参数 - 添加 value
属性如果 T
不是 undefined
如果 T
未定义。 (这只是更复杂逻辑的虚拟示例,但由于类型是问题,所以应该足够了)function asyncGet<T>(initialState: AsyncState<T>) {
return typeof initialState.value !== 'undefined'
? (s: AsyncState<T>) => ({ ...initialState })
: (s: AsyncState) => ({ loading: initialState.loading, error: initialState.error });
}
const first: AsyncState<string> = {
loading: true,
error: null,
value: ""
}
const second: AsyncState<string> = {
loading: true,
error: null,
value: ""
}
const creator = asyncGet(first);
/*
Argument of type 'AsyncState<string>' is not assignable to parameter of type 'AsyncState<string> & AsyncState<undefined>'.
Type 'AsyncState<string>' is not assignable to type 'AsyncState<undefined>'.
Type 'string' is not assignable to type 'undefined'.
*/
creator(second);
这是typescript playground .
最佳答案
您可以通过创建需要推断 T
的实际类型的返回函数来解决此问题。通用的。
function asyncGet<T>(initialState: AsyncState<T>) {
return typeof initialState.value !== "undefined"
? (s: AsyncState<T>) => ({ ...initialState })
: <U>(s: AsyncState<U>) => ({
loading: initialState.loading,
error: initialState.error
});
}
也就是说,如果你试图通过这样调用来覆盖 TypeScript 的推理,这会给你带来麻烦:
asyncGet<string>({ loading: true, error: null })
更好的解决方案是使用条件类型来指定函数有条件地使用对返回函数的调用的推断值。
function asyncGet<T>(initialState: AsyncState<T>):
<U>(s: AsyncState<[T] extends [undefined] ? U : T>) =>
AsyncState<[T] extends [undefined] ? U : T> {
return typeof initialState.value !== "undefined"
? (s) => ({ ...initialState })
: (s) => ({
loading: initialState.loading,
error: initialState.error
});
}
关于 typescript 可选的通用属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57860176/