-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: Updated Typescript types. #11193
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/get-appsmith/appsmith/GhTvujQpg7ffVjTSGSkPHNv6j5KB |
|
||
function* createApplication() { | ||
const userOrgs: Organization[] = yield select(getOnboardingOrganisations); | ||
const currentUser = yield select(getCurrentUser); | ||
const currentUser: User | undefined = yield select(getCurrentUser); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For such selectors or function where we know that return types cannot be undefined/null, we should wrap the return values of these functions/selectors with a function like below and reduce type.
function shouldBeDefined<T>(argument: T | undefined | null, message: string = 'some error message to default to'): T {
if (argument === undefined || argument === null) {
throw new TypeError(message);
}
return argument;
}
Here the return value of the getCurrentUser can be wrapped with shouldBeDefined to get the type we expect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your suggestions. As discussed yesterday we have many selectors that use .find()
and therefore return T | undefined
. We can either wrap all our selectors with the above function or we can improve the types like making the actionId
of type keyof typeof state.actions
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yaldram That might not work since the return type of .find() itself, is T | undefined
.
Also, we should only wrap the return where we are sure that it cannot be undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -161,8 +164,11 @@ export function* closeModalSaga( | |||
let widgetIds: string[] = []; | |||
// If modalName is provided, we just want to close this modal | |||
if (modalName) { | |||
const widget = yield select(getWidgetByName, modalName); | |||
widgetIds = [widget.widgetId]; | |||
const widget: FlattenedWidgetProps | undefined = yield select( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should write and use a utility type here like type MayNotExist<T> = T | undefined;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks make sense, we will first try to handle the T | undefined
cases in the selectors if a selector is returning T | undefined
I will replace all the above type with type MayNotExist<T> = T | undefined;
app/client/src/sagas/PluginSagas.ts
Outdated
@@ -73,10 +76,16 @@ function* fetchPluginFormConfigsSaga() { | |||
pluginIdFormsToFetch.add(apiPlugin.id); | |||
} | |||
for (const id of pluginIdFormsToFetch) { | |||
pluginFormRequests.push(yield call(PluginsApi.fetchFormConfig, id)); | |||
const response: GenericApiResponse<PluginFormPayload> = yield call( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to standardize the names for request and response types. This needs to done across the code base. Naming convention needs to be discussed and decided. I vote for ${api}RequestData and ${api}ResponseData. So in this case, the types would be FetchFormConfigRequestData
and FetchFormConfigResponseData
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion. @riodeuno please provide your inputs.
@@ -142,7 +142,7 @@ export const getCurrentPageName = createSelector( | |||
getPageListState, | |||
(pageList: PageListReduxState) => | |||
pageList.pages.find((page) => page.pageId === pageList.currentPageId) | |||
?.pageName, | |||
?.pageName || "PAGE_NAME_NOT_FOUND", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throw error here when pageName is not found. Makes sure the selector always return string. Refer
https://github.com/appsmithorg/appsmith/pull/11193/files#r811332675
@arunvjn @riodeuno I am leaving behind some of my findings : -
|
Got some answers for typing redux-saga - redux-saga/redux-saga#2251 |
@@ -35,10 +35,10 @@ export interface QueryConfig { | |||
queryString: string; | |||
} | |||
|
|||
export interface ActionCreateUpdateResponse extends ApiResponse { | |||
export type ActionCreateUpdateResponse = ApiResponse & { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yaldram Could you explain why we have changed interface
to type
here?
The reason for asking, is that if we have a standard reason for deciding one over the other, we can make it a practice in all of our codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually we have our ApiResponse
as a generic type here, before it was an interface so I have changed some interfaces to types like : -
type TemplateResponse = ApiResponse<Template>
and if you want to add more params to the type just extend it using &
like -
type JSCollectionCreateUpdateResponse = ApiResponse & { id: string }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All API responses are of the type ApiResponse. We are doing something wrong here.
Did you mean to do something like ApiResponse<Template & { id: string }> ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @arunvjn no actually this id field of type string
is an additional field on the response and not part of the data field.
request: ActionApiResponseReq; | ||
errorType?: string; | ||
}; | ||
export type ActionExecutionResponse = ApiResponse<{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am wondering if this could be achieved by using interface
extends ApiResponse
.
@yaldram I believe we had discussed the advantage of this approach. Could you mention it here so that we can consider this consistently further into the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a discussion with @arunvjn where he suggested to use ApiResponse<T>
as a Generic type we had a GenericApiResponse
previously but it had the same fields as ApiResponse
with an additional field that can be undefined. We are now replacing all our extends ApiResponse
to use the generic version of it.
old version : -
export type ApiResponse = {
responseMeta: ResponseMeta;
data: any;
code?: string;
};
export interface ActionExecutionResponse {
responseMeta: ResponseMeta;
data: {
body: Record<string, unknown> | string;
headers: Record<string, string[]>;
statusCode: string;
isExecutionSuccess: boolean;
request: ActionApiResponseReq;
errorType?: string;
};
clientMeta: {
duration: string;
size: string;
};
}
now : -
export type ApiResponse<T = unknown> = {
responseMeta: ResponseMeta;
data: T;
code?: string;
};
export type ActionExecutionResponse = ApiResponse<{
body: Record<string, unknown> | string;
headers: Record<string, string[]>;
statusCode: string;
isExecutionSuccess: boolean;
request: ActionApiResponseReq;
errorType?: string;
}> & {
clientMeta: {
duration: string;
size: string;
};
};
import { Variable, JSAction } from "entities/JSCollection"; | ||
import { PluginType } from "entities/Action"; | ||
export interface JSCollectionCreateUpdateResponse extends ApiResponse { | ||
|
||
export type JSCollectionCreateUpdateResponse = ApiResponse & { | ||
id: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you confirm if this is supposed to be something like ApiResponse<{id: string}>
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it should be : -
export type JSCollectionCreateUpdateResponse = ApiResponse & {
id: string;
}
The above type has all the fields of ApiResponse, plus the id: string
field.
old version : -
export interface JSCollectionCreateUpdateResponse extends ApiResponse {
id: string;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this should be ApiResponse<{id: string}>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @arunvjn actually we have an additional field here id of type string
which will not be part of the data field
This PR has not seen activitiy for a while. It will be closed in 7 days unless further activity is detected. |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Description
4.2.4
& fix typescript types.Fixes #11091
Fixes #9134
Type of change
How Has This Been Tested?
yarn start
the code should compile without any typescript errors in the console.Checklist: