async function as type in hacklang - async-await

I am trying to build a shape where key is string and value is function. This works fine for regular functions but gives error for async functions. Following is what I am trying to do
const type TAbc = shape(
'works' => (function (): string),
'doesnt_work' => (async function(): Awaitable<string>)
);
This results in error A type specifier is expected here.Hack(1002)
Encountered unexpected text async, was expecting a type hint.Hack(1002)
Is this illegal in Hacklang? If yes then would like to know why?

async function (): T is illegal in Hacklang. The suggested way to do this is by defining it in the return type, Awaitable<T>.
So to get this working we can do this
const type TAbc = shape(
'sync' => (function (): string),
'async' => (function(): Awaitable<string>)
);
And while initialising an instance of this type we can internally call an async function. For eg:
$abc = shape(
'async' => function(): Awaitable<string> {
return someAsyncFunction();
});

Related

Cypress multiple arrow function parameters?

So I'm just starting to learn Typescript with Cypress and I noticed this in a page I was reading about here: https://medium.com/#NicholasBoll/cypress-io-scaling-e2e-testing-with-custom-commands-6b72b902aab
export const updateTodo = (name: string) => ($todo: JQuery) => {
cy.wrap($todo).within(() => {
cy.get('label').dblclick()
cy.get('.edit').clear().type(`${name}{enter}`)
})
So I'm still new to typescript and I understand I think that the Jquery element is the subject parameter although I'm still a little bit unsure at what would represent a "Jquery" element/parameter in Cypress.
However what confused me is the fact that there are two fat arrow parameter sections... I've not seen that before? What exactly does that mean? Especially when further down it's called as such (With just a string):
it('should update a todo', () => {
createTodo('Learn Cypress Command API')
.then(updateTodo('Learn Cypress composition'))
.then(getTodoName)
.should('equal', 'Learn Cypress composition')
})
Can anyone explain what's going on here?
Two fat arrows just means the function is returning another function.
So
export const updateTodo = (name: string) => ($todo: JQuery) => {
cy.wrap($todo).within(() => {
cy.get('label').dblclick()
cy.get('.edit').clear().type(`${name}{enter}`)
})
is equivalent to
export const updateTodo = (name: string) => { // outer function
return ($todo: JQuery) => { // inner function
cy.wrap($todo).within(() => {
cy.get('label').dblclick()
cy.get('.edit').clear().type(`${name}{enter}`)
})
Where you use the double-fat-arrow function is another shorthand,
This
.then(updateTodo('Learn Cypress composition'))
is shorthand for this
.then((name: string) => updateTodo(name)('Learn Cypress composition'))
where the double brackets updateTodo()() calls the outer function then the inner function.
Or even longer syntax:
.then((name: string) => {
const innerFn = updateTodo(name);
return innerFn('Learn Cypress composition');
})

Argument of type is not assignable to parameter of type 'never' mapDispatchToProps

I have a typescript error, which i cannot figure out. I get this "Argument of type is not assignable to parameter of type 'never'" error. I have read about this error message, but cant figure out how to solve my issue anyway. So i have the following code:
My reducercode:
export const setInfoGDPRAction = createAction(InfoActionTypes.SET_GDPR, (resolve) => (acceptedgdpr: boolean) => resolve(acceptedgdpr));
Then in my hooks-component:
type Action = ActionType<typeof actions>; // (when i hover this it says Action = never)
const mapStateToProps = (state: ApplicationState): RootProps => ({
data: state.data,
} as RootProps);
const mapDispatchToProps = (dispatch: React.Dispatch<Action>, props: RootProps): RootProps => ({
setGDPRData: (accepted: boolean) => dispatch(actions.setInfoGDPRAction(accepted)),
} as RootProps);
export default connect(mapStateToProps, mapDispatchToProps)(Root);
Can anyone tell me how i can write this so it will work? :)
Thanks.

compilation problem/error while using an rxjs switchmap

Hi i am getting an error in my code . I have an angular 5 formGroup and i am trying to use the pipe operation and switchMap inside.
However it give me an error. The following is my code snippet.
this.formGroup.valueChanges.pipe(
switchMap(
(formValue) => {
console.log(formValue);
}
)
).subscribe();
the error i is as below
Argument of type '(formValue: any) => void' is not assignable to parameter of type '(value: any, index: number) => ObservableInput<{}>'.
Type 'void' is not assignable to type 'ObservableInput<{}>'.ts(2345)
really appreciate any help
thank you
You have to return an observable in the switchMap. switchMap switches to a new observable and you can do it conditionally based on the previous value.
If you want to just console.log, I would use tap.
this.formGroup.valueChanges.pipe(
tap(
(formValue) => {
console.log(formValue);
}
),
).subscribe();
====================== Edit ==========================
I assume this.generatePerformanceGraph(formValue); is a regular function and it doesn't return an observable, then you can do it in the subscribe.
this.formGroup.valueChanges.pipe(
tap( // you can remove this tap, it is just for logging
(formValue) => {
console.log(formValue);
}
),
).subscribe(formValue => {
this.generatePerformanceGraph(formValue);
});

What Is the behavior of forkJoin when it is not In a SwitchMap/MergeMap in Epics

I want to understand what happens when I directly pipe to an action$ and try to use forkJoin operator
const action1 = { type: "ACTION_1" };
const action2 = { type: "ACTION_2" };
in a switchMap forkJoin works fine.
export const testForkJoinSwitchMap: Epic<Action> = action$ =>
action$.pipe(
ofType(action1),
switchMap(() =>
forkJoin(
from(fetch("https://api.github.com/users")).pipe(
map((res: any) => {
return res;
})
)
)
),
map((data: any) => {
// do something with data
return action2;
})
);
If I took it out of the switchMap then:
export const testForkJoin: Epic<Action> = action$ =>
action$.pipe(
ofType(action1),
forkJoin(from(fetch("https://api.github.com/users"))).pipe(
map((response: any) => {
return action2;
})
)
);
I get the typing error:
Argument of type 'Observable<{ type: string; }>' is not assignable to parameter of type 'OperatorFunction<{}, Action<any>>'.
I want to know why it does not compile? and the reason of the type mismatch, what makes the epics without the forkJoin invalid in this case?
edit: I know that forkJoin is not meaningful for a single observable, but I put 1 to keep the example smaller
observable.pipe() only takes operators inside it.
forkJoin is an operator which returns an observable that's why you get that error. Argument of type 'Observable' is not assignable to parameter of type 'OperatorFunction' i.e forkJoin which returns an observable is not assignable to type of operator function.
switchMap, on the other hand, is an operator which returns an OperatorFunction and operates on an observable that's why your first approach worked. switchMap(() => someObservable) and someObservable in this case is forkJoin()
It's also evident from your imports. You might have imported forkJoin from rxjs library whereas switchMap from rxjs/operators library.

RxJs: Map to anonymous type object

I've created this Observable:
private accounts$: Observable<{type: string, alias: string}>;
I need to map an Array<Account> to an stream of {type, alias} object. Up to now, I've tried this:
this.accounts$ = this.store$
.select(fromRoot.getDBoxAccountEntities)
.flatMap(accounts => accounts.map(account => {type: 'dbox', alias: account.dboxAccount}))
...
However I'm getting compilation error messages.
Any ideas?
You are returning an object from your arrow function but the brackets suggest function body. You need () around your returned object:
.flatMap(accounts => accounts.map(account => ({type: 'dbox', alias: account.dboxAccount})))

Resources