-
Notifications
You must be signed in to change notification settings - Fork 153
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
Make the type of the return value more precise #46
Conversation
If the first return value (error) is null, then this change implies that the second return value is not `undefined`. It solves a problem I was facing: getting `Type 'APIResponse<any> | undefined' is not assignable to type 'APIResponse<any>'` type error on the last row of the following Vuex (with vuex-module-decorators) example: ```js @action({ rawError: true }) public async deleteAsset(asset: Asset): Promise<APIResponse> { this.context.commit('setIsLoading', true); const [err, response] = await to<APIResponse, APIError>(deleteAsset(asset)); this.context.commit('setIsLoading', false); if (err) { throw err; } this.context.commit('setAssetDeleted', asset); return response; } ```
@scopsy, can we get this merged? |
@scopsy ran into problems with this today - what do you think about merging this? |
Co-authored-by: Karl Horky <karl.horky@gmail.com>
@scopsy nice, thanks for the merge! Will this be released in a new version |
Hi! Yes this will be released in an new minor version. Hopefully today :) |
Great. I'm looking forward to the release. |
FYI, this was released yesterday as v3.0.0 |
Adds the changes in scopsy/await-to-js#46 to our local type definitions (which exist because I'm waiting on scopsy/await-to-js#47).
Adds the changes in scopsy/await-to-js#46 to our local type definitions (which exist because I'm waiting on scopsy/await-to-js#47).
Adds the changes in scopsy/await-to-js#46 to our local type definitions (which exist because I'm waiting on scopsy/await-to-js#47).
Does this currently work? I'm still having to cast user as UserEntity because the inferred type is createUser = async (userToCreate: Omit<UserEntity, 'id'>): Promise<UserDTO> => {
const [err, user] = await to(this.UserRepository.createUser(userToCreate));
if (err) {
this.Logger.error('Failed to create user.', err.message);
throw err;
}
const userDTO = UserMapper.userEntityToDTO(user as UserEntity);
return userDTO;
}; |
@WilliamStephens it likely doesn't work. I don't know why. I stopped using await-to-js with typescript because of it. |
If the types of Destructuring makes TypeScript "forget" about the relationship between the two variables const results = await to(this.UserRepository.createUser(userToCreate));
if ('err' in results) {
this.Logger.error('Failed to create user.', results.err.message);
throw results.err;
}
const userDTO = UserMapper.userEntityToDTO(results.user); // ✅ results.user = User type
return userDTO; The overarching feature set to allow things like destructuring is described as "Correlated Union Types", which some of the newer (and upcoming) versions of TypeScript support, at least partially: |
Hmm, yeah seems like destructuring is whats causing it. I converted the return type to be an object to make it a little more explicit. export function to<T, U = Error>(
promise: Promise<T>,
errorExt?: object
): Promise<{ err: U; data: undefined } | { err: null; data: T }> {
return promise
.then((data: T) => ({ err: null, data }))
.catch((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt);
return { err: parsedError, data: undefined };
}
return { err, data: undefined };
});
} Then I can do something like this createUser = async (userToCreate: Omit<UserEntity, 'id'>): Promise<UserDTO> => {
const result = await to(this.UserRepository.createUser(userToCreate));
if (result.err) {
this.Logger.error('Failed to create user.', result.err.message);
throw result.err;
}
const userDTO = UserMapper.userEntityToDTO(result.data);
return userDTO;
};
} Instead of doing something like Thanks for the replies! |
If the first return value (error) is null, then this change implies that the second return value is not
undefined
.It solves a problem I was facing: getting
Type 'APIResponse<any> | undefined' is not assignable to type 'APIResponse<any>'
type error on the last row of the following Vuex (with vuex-module-decorators) example: