如何键入多个收益生成器(redux-saga)
How to type multiple yield generator (redux-saga)
我们的 redux-saga 生成器包含多个 yield 语句,return 不同的结果。
我需要帮助正确输入它们。
这是一个例子:
const addBusiness = function* addBusiness(action: AddBusinessActionReturnType): Generator<
Promise<Business> | SelectEffect | PutEffect<{ payload?: ActionPayload<Array<Business>>; type: string }>,
void,
Business | BusinessesContainer
> {
const { url, showToast = true } = action.payload;
const businessDetails: Business = yield Network.get<Business>( // ts error: Type 'Business | BusinessesContainer' is not assignable to type 'Business'.
`businesses?url=${url}`,
);
if (showToast) {
const getBusinessesFromState = (state: AppState) => ({
...state.business.businesses,
});
const businesses: BusinessesContainer = yield select(getBusinessesFromState); // ts error: Type 'Business | BusinessesContainer' is not assignable to type 'BusinessesContainer'
onAddBusinessSuccessToast(businesses, businessDetails);
}
yield put({ // ts error: Type 'SimpleEffect<"PUT", PutEffectDescriptor<{ type: string; payload: Business[]; }>>' is not assignable to type 'SelectEffect'
type: constants.SAVE_BUSINESS_REQUEST,
payload: [businessDetails],
});
在上面的评论中,您可以看到我们得到的 ts 错误。
任何帮助,将不胜感激。
谢谢
看来你肯定是犯了一些过度打字的错误。当然 yield Network.get<Business>()
return 是 Business
对吧?如果您分配给它的值是 Business
.
,则不必写 const businessDetails: Business
这些生成器 return 类型可能真的很难正确输入,但 Typescript 足够聪明,可以找出正确的类型。您可以完全关闭它,这样会很好。如果您很难找出正确的类型,您可以暂时删除 return 类型以查看推断的类型是什么。这就是我如何解决您的第一个问题,即联合 Business | BusinessesContainer
需要更改为交集 Business & BusinessesContainer
.
我不知道 ActionPayload
类型是什么,但似乎没有必要。您将 put
操作的负载输入为 ActionPayload<Array<Business>>
,但 Array<Business>
本身是正确的。当您始终提供 payload
时,没有理由将其设为可选。
这两项更改暂时解决了您的打字稿问题……。我经常看到 API 调用在 call
effect 中执行,这会使类型更加复杂。但我不确定 call
是否真的需要。
const addBusiness = function* addBusiness(action: AddBusinessActionReturnType): Generator<
Promise<Business> | SelectEffect | PutEffect<{ payload: Array<Business>; type: string }>,
void,
Business & BusinessesContainer
> {
const { url, showToast = true } = action.payload;
const businessDetails: Business = yield Network.get<Business>( `businesses?url=${url}` );
if (showToast) {
const getBusinessesFromState = (state: AppState) => ({
...state.business.businesses,
});
const businesses: BusinessesContainer = yield select(getBusinessesFromState);
onAddBusinessSuccessToast(businesses, businessDetails);
}
yield put({
type: "SAVE_BUSINESS_REQUEST",
payload: [businessDetails],
});
}
// dummy types that I filled in to check types
type Business = {
name: string;
id: number;
}
type BusinessesContainer = {
businesses: Business[];
}
const Network = {
get: async <T>(url: string): Promise<T> => {
return {} as unknown as T;
}
}
type AddBusinessActionReturnType = {
type: string;
payload: {
showToast?: boolean;
url: string;
}
}
type AppState = {
business: {
businesses: BusinessesContainer;
}
}
const onAddBusinessSuccessToast = (businesses: BusinessesContainer, businessDetails: Business) => undefined;
我们的 redux-saga 生成器包含多个 yield 语句,return 不同的结果。 我需要帮助正确输入它们。
这是一个例子:
const addBusiness = function* addBusiness(action: AddBusinessActionReturnType): Generator<
Promise<Business> | SelectEffect | PutEffect<{ payload?: ActionPayload<Array<Business>>; type: string }>,
void,
Business | BusinessesContainer
> {
const { url, showToast = true } = action.payload;
const businessDetails: Business = yield Network.get<Business>( // ts error: Type 'Business | BusinessesContainer' is not assignable to type 'Business'.
`businesses?url=${url}`,
);
if (showToast) {
const getBusinessesFromState = (state: AppState) => ({
...state.business.businesses,
});
const businesses: BusinessesContainer = yield select(getBusinessesFromState); // ts error: Type 'Business | BusinessesContainer' is not assignable to type 'BusinessesContainer'
onAddBusinessSuccessToast(businesses, businessDetails);
}
yield put({ // ts error: Type 'SimpleEffect<"PUT", PutEffectDescriptor<{ type: string; payload: Business[]; }>>' is not assignable to type 'SelectEffect'
type: constants.SAVE_BUSINESS_REQUEST,
payload: [businessDetails],
});
在上面的评论中,您可以看到我们得到的 ts 错误。 任何帮助,将不胜感激。 谢谢
看来你肯定是犯了一些过度打字的错误。当然 yield Network.get<Business>()
return 是 Business
对吧?如果您分配给它的值是 Business
.
const businessDetails: Business
这些生成器 return 类型可能真的很难正确输入,但 Typescript 足够聪明,可以找出正确的类型。您可以完全关闭它,这样会很好。如果您很难找出正确的类型,您可以暂时删除 return 类型以查看推断的类型是什么。这就是我如何解决您的第一个问题,即联合 Business | BusinessesContainer
需要更改为交集 Business & BusinessesContainer
.
我不知道 ActionPayload
类型是什么,但似乎没有必要。您将 put
操作的负载输入为 ActionPayload<Array<Business>>
,但 Array<Business>
本身是正确的。当您始终提供 payload
时,没有理由将其设为可选。
这两项更改暂时解决了您的打字稿问题……。我经常看到 API 调用在 call
effect 中执行,这会使类型更加复杂。但我不确定 call
是否真的需要。
const addBusiness = function* addBusiness(action: AddBusinessActionReturnType): Generator<
Promise<Business> | SelectEffect | PutEffect<{ payload: Array<Business>; type: string }>,
void,
Business & BusinessesContainer
> {
const { url, showToast = true } = action.payload;
const businessDetails: Business = yield Network.get<Business>( `businesses?url=${url}` );
if (showToast) {
const getBusinessesFromState = (state: AppState) => ({
...state.business.businesses,
});
const businesses: BusinessesContainer = yield select(getBusinessesFromState);
onAddBusinessSuccessToast(businesses, businessDetails);
}
yield put({
type: "SAVE_BUSINESS_REQUEST",
payload: [businessDetails],
});
}
// dummy types that I filled in to check types
type Business = {
name: string;
id: number;
}
type BusinessesContainer = {
businesses: Business[];
}
const Network = {
get: async <T>(url: string): Promise<T> => {
return {} as unknown as T;
}
}
type AddBusinessActionReturnType = {
type: string;
payload: {
showToast?: boolean;
url: string;
}
}
type AppState = {
business: {
businesses: BusinessesContainer;
}
}
const onAddBusinessSuccessToast = (businesses: BusinessesContainer, businessDetails: Business) => undefined;