I’m encountering some problems when starting a new Frontity project with TypeScript. I’ll list them here to discuss how to approach them:
- The
package.json
in the project’s root needs typescript
declared as a dev dependency. This should be done in frontity create -t
.
- When you run
frontity create-package -t
, it is not yet implemented the support for this option (and is not explained in the help
command, which leads the developer to believe that there is a bug).
- The
@types/react
package is not installed after frontity create
and I need to declare it as a dependency somewhere. I think this should be avoidable. We could declare @types/react
as a dependency instead of a dev dependency in @frontity/core
or maybe, so only people that uses the -t
option will download the @types
packages, we could declare these packages as dev dependencies in the project’s root, like typescript
, when we run frontity create -t
(I don’t like this second way, though).
- I’m not sure if there needs to be a
tsconfig.json
file in the project’s root. So far it didn’t seem necessary though.
EDIT: I was doing fine until I used Object.values()
which needs the target
set to es2017
, and only setting that will override all settings so I had to copy all the settings used in the frontity
repo.
- There is a
@types/react-helmet
dependency here that seems unnecessary, as react-helmet-async
is being used.
- When you add a new field to the
package
export object, like { state: { theme: { some: "field" } } }
, if there isn’t at least one field at the same deep defined in the types, TypeScript won’t complain for declaring a field not typed. I think this is a bug.
PS: I can work on this things once we decide how to fix them.
I’ve been playing a bit and I’d like to know what do you think about this pattern, if it’s a good option or if it presents any problem that I might be missing:
// types.ts
import React from "react";
import { Package, Connect as BaseConnect } from "frontity/types";
import Source from "@frontity/source";
import Router from "@frontity/router";
interface Nispero extends Package {
name: "nispero-theme";
roots: {
theme: React.FC;
};
state: {
theme: {};
};
actions: {
theme: {};
};
}
export default Nispero;
type Packages = Source & Router & Nispero;
type Connect<Props extends object = {}> = BaseConnect<Packages, Props>;
export { Connect };
// src/root.tsx
import React from "react";
import { connect } from "frontity";
import { Connect } from "../types";
const Root: React.FC<Connect<{ someProp: string }>> = props => (
<div>
<p>{props.someProp}</p>
<p>{props.state.frontity.title}</p>
<pre>{props.state.theme}</pre>
</div>
);
export default connect(Root);
type Packages = Source & Router & Nispero;
In my opinion, I’d be more picky about the things your package needs from Source
or Router
, instead of including everything by default.
type Connect<Props extends object = {}> = BaseConnect<Packages, Props>;
Re-exporting the Connect
, already hooked to your package seems fine to me
@luisherranz the Analytics example is broken I get TS2749: ‘Analytics’ refers to a value but is being used as type.
while adding to the theme types.ts
analytics?: Analytics["actions"];
Could you advise?
Just a quick suggestion, I think you might want to try analytics?: Analytics['actions']['analytics']
, as each package in Frontity might have more than one namespace, this needs to be added after the ['actions']
bit.
@f.napoleoni: did you solve it with @orballo’s suggestion?
By the way, welcome to the community!