Skip to content
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

Strict types: Await block with Observables using the $ syntax, Property 'then' does not exist on '' #358

Closed
AlexAegis opened this issue Jul 25, 2020 · 6 comments
Labels
bug Something isn't working Fixed Fixed in master branch. Pending production release.

Comments

@AlexAegis
Copy link

Based on this issue and this comment rxjs observables with await blocks are supported. sveltejs/svelte#2571 (comment)

And indeed this code snippet does the job and works (Except errors and the unresolved state but that a different issue), but it also produces a TypeScript error, and one more if strict settings (noImplicitAny to be precise) are enabled.

tsconfig.json

{
	"compilerOptions": {
		"strict": true,
		"noImplicitAny": true, // set to `false` to avoid ts(7006)
	}
}

app.svelte

<script lang="ts">
	import { interval, Subject } from 'rxjs';
	import { onMount } from 'svelte';

	const s$ = new Subject<number>();

	onMount(() => {
		interval(500).subscribe((i) => s$.next(i));
	});
</script>

{#await $s$}
	Loading...
{:then value} <!-- Property 'then' does not exist on type 'number'.ts(2339) -->
				<!-- Parameter 'value' implicitly has an 'any' type.ts(7006) -->
<!-- Both of these errors appear on the {:then block, but when hovering over
the `value` word in the `then` block it correctly shows the type as `number`,
while if I hover over the one below, it says `any` -->
	Value: {value}
{:catch e} <!-- Parameter 'e' implicitly has an 'any' type.ts(7006) -->
	Error: {e}
{/await}

any in a catch should always be allowed as you can't even specify types of errors in regular catch blocks either. TS knows this, of course, and the interesting part is when using Promises in the template, e in the
:catch block still has an any type but that does not produce an error, only with Observables.

@AlexAegis AlexAegis added the bug Something isn't working label Jul 25, 2020
@dummdidumm
Copy link
Member

It's a svelte2tsx issue, the code assumes it's a promise. Honestly I did not even know this is possible.

@AlexAegis
Copy link
Author

AlexAegis commented Jul 25, 2020

Well it seems it's just half-supported(?), and I opened another issue on the main repo sveltejs/svelte#5206 because the await and error blocks never render with regular observables. There is timhall's https://github.com/timhall/svelte-observable lib which does solve this problem but the Property 'then' does not exist on type 'number'.ts(2339) error still stands with that too.

(The mentioned issue contains a larger snippet with the mentioned svelte-observable case, if that helps)

@jasonlyu123
Copy link
Member

jasonlyu123 commented Jul 25, 2020

I look at the source of svelte's handle_promise, It seems like if the value awaiting is not a PromiseLike, i.e. object with then method, it will just pass the value to the then block. So technically you can await anything
https://svelte.dev/repl/07ff97ba27a4403fa9e0f239cfc536e3?version=3.24.0
Doesn't know this. but This is the behavior of await keyword in javascript
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await

Returns the fulfilled value of the promise, or the value itself if it's not a Promise.

Along with the issue mention here
#298 (comment)
We should have a new helper function to handle then block and catch block.

By the way, if there is an error it won't be handled. because it doesn't wrap it with a try-catch. but

PromiseLike.then(value => {}, error => {})

, when the value awaiting is a PromiseLike

@AlexAegis
Copy link
Author

So technically you can await anything

And I believe this should be reflected by the types aswell, as I said the solution using that observe helper function from https://github.com/timhall/svelte-observable does make it work as expected (it wraps it in a svelte store), it's just svelte-check that complains about Property 'then' does not exist on type 'number'.ts(2339)

@jasonlyu123
Copy link
Member

Yeah. it needs to be supported. Typescript also allow you to await on anything. But it also got me thinking what the point of this await anymore? You can't catch any errors even if svelte wrap a try catch in the generated code. Because it's similar to the following:

let a = 1
try {
  const value = await a;
} catch (error) {
  //Do something
}

@dummdidumm
Copy link
Member

True, catching will never work, but the "show loading while no value, show then if there's a value" will work.

@jasonlyu123 jasonlyu123 added the Fixed Fixed in master branch. Pending production release. label Jul 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Fixed Fixed in master branch. Pending production release.
Projects
None yet
Development

No branches or pull requests

3 participants