Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

add types for stores #1601

Merged
merged 8 commits into from
Oct 26, 2020
Merged

add types for stores #1601

merged 8 commits into from
Oct 26, 2020

Conversation

TheComputerM
Copy link
Contributor

Fixes #1556

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with npm test and lint the project with npm run lint

@TheComputerM TheComputerM mentioned this pull request Oct 13, 2020
4 tasks
query: Record<string, string | string[]>;
error?: Error;
}
export { PageContext as Page } from '@sapper/app/types';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also imported PageContext from @sapper/app/types as to not re-declare it.

Copy link
Contributor

@ehrencrona ehrencrona left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :)

@bjon
Copy link

bjon commented Oct 13, 2020

import { PageContext } from "@sapper/app/types"; doesn't seem to work with vscode. It still shows:

(alias) stores(): {
    preloading: Readable<boolean>;
    page: Readable<any>;
    session: Writable<any>;
}
import stores

@bjon
Copy link

bjon commented Oct 13, 2020

server.ts is created like this:

polka() // You can also use Express
	.use(
		compression({ threshold: 0 }),
		sirv('static', { dev }),
		sapper.middleware()
	)
	.listen(PORT, err => {
		if (err) console.log('error', err);
	});

so opts in middleware, should be optional.

export function middleware(opts?: MiddlewareOptions): Handler;

@TheComputerM
Copy link
Contributor Author

import { PageContext } from "@sapper/app/types"; doesn't seem to work with vscode. It still shows:

(alias) stores(): {
    preloading: Readable<boolean>;
    page: Readable<any>;
    session: Writable<any>;
}
import stores

I think PageContext has to be a type instead of an interface for this to work, please correct me if I am wrong.

@bjon
Copy link

bjon commented Oct 13, 2020

@TheComputerM Both type or interface should work. I just don't understand the "magic" behind @sapper/app/types.
How can vscode access it?

@TheComputerM
Copy link
Contributor Author

So, shall I convert @sapper/app/types to ./src/app/types?

@bjon
Copy link

bjon commented Oct 13, 2020

That file doesn't exist either?

The only way I can get it to work, is to declare the namespace, directly in the index.d.ts

declare module '@sapper/app/types' {
  export interface PageContext {
    host: string;
    path: string;
    params: Record<string, string>;
    query: Record<string, string | string[]>;
    error?: Error;
  }
}

But now we're back to square one again :)

@TheComputerM
Copy link
Contributor Author

This is the file

@bjon
Copy link

bjon commented Oct 13, 2020

Yes, but only in the source. I can't find it anywhere in node_modules/sapper or src/node_modules/@sapper.

If its not included in the sapper dist, or auto-generated [@]sapper, I dont see how we can import it.

@TheComputerM
Copy link
Contributor Author

So how do we fix this?

@bjon
Copy link

bjon commented Oct 13, 2020

If @sapper/app/types and @sapper/internal/manifest-server are supposed to work, it might be a bug when sapper generates the code?

@bjon
Copy link

bjon commented Oct 13, 2020

One workaround would be to add

declare module '@sapper/app/types' {
  export interface PageContext {
    host: string;
    path: string;
    params: Record<string, string>;
    query: Record<string, string | string[]>;
    error?: Error;
  }
}

and remove it, when the import works?

@bjon
Copy link

bjon commented Oct 13, 2020

But im no expert here. I just want auto-complete to work :)

@TheComputerM
Copy link
Contributor Author

Ok, If someone approves this, I will add this.

@bjon
Copy link

bjon commented Oct 13, 2020

And also, export function start(opts: { target: Node }): Promise<void>; should be export function start(opts: { target: Element }): Promise<void>;, cause document.querySelector returns an Element

sapper.start({
  target: document.querySelector(`#sapper`),
});

@bjon
Copy link

bjon commented Oct 13, 2020

To avoid compile error its should probably be export function start(opts: { target: Element | null }): Promise<void>;.
document.querySelector returns Element | null

or maybe better, change sapper-template to convert TS to

sapper.start({
  target: document.querySelector(`#sapper`) as Element,
});

@AnandChowdhary
Copy link
Contributor

To avoid compile error its should probably be export function start(opts: { target: Element | null }): Promise<void>;.
document.querySelector returns Element | null

or maybe better, change sapper-template to convert TS to

sapper.start({
  target: document.querySelector(`#sapper`) as Element,
});

This is what we do, maybe it's better to ensure it exists instead of typecasting?

const target = document.querySelector("#sapper");

if (target)
  sapper.start({
    target,
    hydratable: true,
  });

@bjon
Copy link

bjon commented Oct 13, 2020

Found one more. In @sapper/app goto(opts), should be optional

@ehrencrona
Copy link
Contributor

ehrencrona commented Oct 15, 2020

This is a useful discussion; the handling of types right now seems wrong. I looked into how the types work: in the tsconfig.json @sapper is defined as an alias for the directory runtime/src:

"paths": {
	"@sapper/*": ["runtime/src/*"]
}

This is the reason why @sapper/internal references work in Sapper code, but not in project code. In project code there simply is no such thing; the only thing resolved under @sapper is what we put in the index.d.ts.

Therefore, those references from index.d.ts to @sapper/internal must be removed. I created #1604 for this. Once that is merged, it should be possible to apply this PR on top of #1604 (though I'm afraid #1604 might cause some controversy and could take time to merge).

@ehrencrona
Copy link
Contributor

On the discussion around whether target in start is Node or an Element: An Element is a Node; Node is the most abstract class. start can handle Nodes so it should be target: Node.

Furthermore, I don't think start can handle target being null. If you can't find the DOM node you want to start the app in, that's an error, which is essentially what the type mismatch says.

Copy link

@bencates bencates left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to parameterize these types to let users type the session and preloaded props.

Comment on lines 51 to 53
export interface Preload {
(this: PreloadContext, page: Page, session: any): object | Promise<object>;
(this: PreloadContext, page: PageContext, session: any): object | Promise<object>;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	export interface Preload<Props = object, Session = any> {
		(this: PreloadContext, page: PageContext, session: Session): Props | Promise<Props>;
	}

Co-authored-by: Ben Cates <[email protected]>
@benmccann
Copy link
Member

@TheComputerM this PR will need to be rebased

Copy link

@bencates bencates left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this might be my fault. GitHub would only allow me to format half of my proposed changes as suggestions.

@@ -28,7 +28,7 @@ declare module '@sapper/server' {
ignore?: Ignore
}

export function middleware(opts?: MiddlewareOptions): Handler;
export function middleware<Session = unknown>(opts?: MiddlewareOptions<Session>): Handler;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works correctly unless we also parameterize MiddlewareOptions

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve TypeScript type definition for stores
7 participants