declare interface AssertionApi<E> {
currentPromise: Promise<void>;
actual: E;
eql(expected: E): Promise<void>;
ok(): Promise<void>;
notOk(): Promise<void>;
}
declare class StringAssertions implements AssertionApi<string> {
constructor(currentThis: Promise<void>, actual: string);
currentPromise: Promise<void>;
actual: string;
eql(expected: string): Promise<void>;
ok(): Promise<void>;
notOk(): Promise<void>;
}
const foo = {
expect<A>(this: Promise<void>, actual: A | Promise<A>): AssertionApi<A> {
const handlePrimitive = (actual: A): AssertionApi<A> => {
let assertionApi: AssertionApi<unknown>;
switch (typeof actual) {
case "string":
assertionApi = new StringAssertions(this, actual);
break;
default:
throw new Error(`Can't handle assertions on a ${typeof actual} type`);
}
return assertionApi as AssertionApi<A>;
};
if (actual instanceof Promise) {
return this.then(() => actual).then((actualPrimitive) =>
// ^^^^^^
// Type 'Promise<AssertionApi<A>>' is missing the following properties from type 'AssertionApi<A>': currentPromise, actual, eql, ok, notOk
handlePrimitive(actualPrimitive),
);
} else {
return handlePrimitive(actual);
}
},
};
#Can I return a non-Promise from a method that needs to wait on its Promise argument?
1 messages · Page 1 of 1 (latest)
In the context of this question, I want to assume that expect's actual is a Promise. I would like to be able to write the code as shown, but it returns a Promise<AssertionApi<A>> instead of a AssertionApi<A>
Is it possible to get the value of the promise within expect, or is that impossible unless I change the return type?
Hi there. First, never call your params this it's a reserved word. Second, if you want to await a promise inside the expect fn and then return the unwrapped value then the expect fn becomes async as well so it returns a promise itself. The only way to workaround is to use a callback that will be fired after a promise resolution.
Basically your expect function behaves synchronously when actual is a value and asynchronously when it's a promise. It's bad behavior as it's unpredictable. You need to change your api
Declaring a this function parameter is a TS feature, it allows you to type annotate what this should be.
never heard of it. Can you give a link for this?
Can't seem to find it in TS handbook.
function greet(this: { name: string }) {
console.log(this.name)
}
const foo = { name: 'foo', greet }
foo.greet()
const bar = { greet }
bar.greet()
//^
// The 'this' context of type '{ greet: (this: { name: string; }) => void; }' is not assignable to method's 'this' of type '{ name: string; }'.
// Property 'name' is missing in type '{ greet: (this: { name: string; }) => void; }' but required in type '{ name: string; }'.