swell-js icon indicating copy to clipboard operation
swell-js copied to clipboard

TypeScript support

Open asia-jankowska00 opened this issue 3 years ago • 25 comments

I'm writing my application in TypeScript and would like to see TypeScript typing support.

asia-jankowska00 avatar Jun 10 '21 08:06 asia-jankowska00

Thanks @asia-jankowska00 for raising this issue. We're currently in the process of adding TS support. cc @rodrigo-swell

greph avatar Jun 10 '21 15:06 greph

Hi! Any progress on this issue?

alinjie avatar Dec 12 '21 14:12 alinjie

Hey @alinjie 👋 , no updates at the moment. Keep an eye on our change log for any announcements.

greph avatar Dec 13 '21 14:12 greph

Hi! Anything new about this?

romainbriand avatar Jul 28 '22 14:07 romainbriand

Seconded, it's a real turn off when you're used to a fully typed workflow.

szydlovski avatar Aug 15 '22 18:08 szydlovski

news on this? :)

markus-gx avatar Oct 10 '22 11:10 markus-gx

It would be so much appreciated + looks like a big part of the job has already been done in the past: https://github.com/swellstores/nextjs-commerce/tree/master/framework/swell/types

romainbriand avatar Oct 10 '22 11:10 romainbriand

I have the same request, but have decided to work on my own implementation of @types/swell-js as I develop with it on our internal codebases.

There is a lot to be typed still, but everything we're using seems to be correct. You can check progress or even copy it to an internal d.ts file from: https://github.com/gusfune/DefinitelyTyped - all commits in this fork are for typing Swell-JS

gusfune avatar Oct 21 '22 10:10 gusfune

Hi @gusfune, thanks for all the work done! Although I'm having some trouble trying to implement your solution, I've copied the same files to my typescript Next.js project but it seems it's not working, I have the error that appears in the picture below, do you imagine any solution?

Screen Shot 2022-10-31 at 15 20 42

FelipeCabreraB avatar Oct 31 '22 18:10 FelipeCabreraB

The typing implementation is not fully done @FelipeCabreraB, so some types are written as any for now. Try to disable eslint warnings for those lines and see if it will work. Otherwise, might need to review your configuration.

gusfune avatar Oct 31 '22 18:10 gusfune

Oh, I forgot one thing, to use it inside a project you need to wrap the tipings with a declare module. Example:

declare module "swell-js" {
  export as namespace swell

  export interface Query {
    limit?: number
  ...ETC
}

gusfune avatar Oct 31 '22 18:10 gusfune

Thanks @gusfune! That worked for me!

FelipeCabreraB avatar Oct 31 '22 18:10 FelipeCabreraB

One last update @FelipeCabreraB - you can now install @types/swell-js directly to your repository. It's been merged the PR I've made.

yarn add -D @types/swell-js or npm i -D @types/swell-js will do.

gusfune avatar Nov 01 '22 09:11 gusfune

Thanks @gusfune!

Additionally, we're including type definitions to swell-js itself, as well as including the remaining type definitions (avoiding any and unknown where possible).

For those who have custom models and fields, we'll be providing a facility to fetch matching response type definitions - that's further down the road, though.

rodrigoddalmeida avatar Nov 01 '22 11:11 rodrigoddalmeida

Why choosing to union in a single type both camel cased and snake cased interfaces? This introduces a load of errors as typescript can't infer which field is from, requiring to redeclare them.

artecoop avatar Dec 30 '22 11:12 artecoop

Why choosing to union in a single type both camel cased and snake cased interfaces? This introduces a load of errors as typescript can't infer which field is from, requiring to redeclare them.

Basically because when getting in the options useCamelCase could affect all returns and this was the easiest way to get the project started. Do you have any suggestions for us to improve? Let me know and we can adjust the project, or you can send a PR and become a maintainer as well.

gusfune avatar Dec 30 '22 11:12 gusfune

I for one use useCamelCase in my swell setup, but when I try to fetch a product, or a cart for example, I've been flooded with errors. I need to manually add all camel cased properties to snake case counterpart using declare module 'swell-js' {...}, which is inconvenient at the minimum

artecoop avatar Dec 30 '22 11:12 artecoop

I for one use useCamelCase in my swell setup, but when I try to fetch a product, or a cart for example, I've been flooded with errors. I need to manually add all camel cased properties to snake case counterpart using declare module 'swell-js' {...}, which is inconvenient at the minimum

Can you share a code snippet that's throwing errors so I can look at it? I have not faced the same problem, but we might find a solution.

gusfune avatar Dec 30 '22 11:12 gusfune

Sure, here's an example of error: Screenshot 2022-12-30 at 12 47 40

I'm using SolidJS and cart?.state.current? is the result of

export interface CartContextState {
    current?: Cart | undefined;
    count: number;
}

const [state, setState] = createStore<CartContextState>({ count: 0 });

const cart: Cart = await Swell.cart.get();
if (cart) {
    setState({ current: cart, count: cart.itemQuantity });
}

artecoop avatar Dec 30 '22 11:12 artecoop

Sure, here's an example of error: Screenshot 2022-12-30 at 12 47 40

I'm using SolidJS and cart?.state.current? is the result of

export interface CartContextState {
    current?: Cart | undefined;
    count: number;
}

const [state, setState] = createStore<CartContextState>({ count: 0 });

const cart: Cart = await Swell.cart.get();
if (cart) {
    setState({ current: cart, count: cart.itemQuantity });
}

Ok, I had the same issue locally. The solution could be using the CamelCase types, this is how I am handling it until we find a better solution to identify the types.

So that would make the code:

export interface CartContextState {
    current?: CartCamelCase | undefined;
    count: number;
}

const [state, setState] = createStore<CartContextState>({ count: 0 });

const cart: CartCamelCase = await Swell.cart.get();
if (cart) {
    setState({ current: cart, count: cart.itemQuantity });
}

Not sure about SolidJS, but in React works like a charm.

@markus-gx do you have any ideas on this?

gusfune avatar Dec 30 '22 12:12 gusfune

I don't think is solidjs per se, more the combination of strictest tsconfig / eslint. Here's mine

tsconfig.json

{
    "compilerOptions": {
        "target": "ESNext",
        "module": "ESNext",
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "jsx": "preserve",
        "jsxImportSource": "solid-js",
        "types": ["vite/client"],
        "noEmit": true,
        "isolatedModules": true,
        "strict": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "allowUnusedLabels": false,
        "allowUnreachableCode": false,
        "exactOptionalPropertyTypes": true,
        "noFallthroughCasesInSwitch": true,
        "noImplicitOverride": true,
        "noImplicitReturns": true,
        "noPropertyAccessFromIndexSignature": true,
        "noUncheckedIndexedAccess": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "importsNotUsedAsValues": "error",
        "checkJs": true,
        "baseUrl": "./",
        "paths": {
            "~/*": ["./src/*"]
        },
    }
}

and .eslintrc.cjs

module.exports = {
    env: {
        browser: true,
        es2021: true
    },
    parser: '@typescript-eslint/parser',
    plugins: ['solid'],
    extends: ['eslint:recommended', 'plugin:solid/typescript'],
    overrides: [],
    parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module'
    },
    rules: {}
};

artecoop avatar Dec 30 '22 14:12 artecoop

I don't think is solidjs per se, more the combination of strictest tsconfig / eslint. Here's mine

tsconfig.json

{
    "compilerOptions": {
        "target": "ESNext",
        "module": "ESNext",
        "moduleResolution": "node",
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "jsx": "preserve",
        "jsxImportSource": "solid-js",
        "types": ["vite/client"],
        "noEmit": true,
        "isolatedModules": true,
        "strict": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "allowUnusedLabels": false,
        "allowUnreachableCode": false,
        "exactOptionalPropertyTypes": true,
        "noFallthroughCasesInSwitch": true,
        "noImplicitOverride": true,
        "noImplicitReturns": true,
        "noPropertyAccessFromIndexSignature": true,
        "noUncheckedIndexedAccess": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "importsNotUsedAsValues": "error",
        "checkJs": true,
        "baseUrl": "./",
        "paths": {
            "~/*": ["./src/*"]
        },
    }
}

and .eslintrc.cjs

module.exports = {
    env: {
        browser: true,
        es2021: true
    },
    parser: '@typescript-eslint/parser',
    plugins: ['solid'],
    extends: ['eslint:recommended', 'plugin:solid/typescript'],
    overrides: [],
    parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module'
    },
    rules: {}
};

What I meant is, if you cast the results to CartCamelCase instead of Cart do you still get the errors mentioned? That'd be my suggestion for now. Here is an example of how I run this in react:

const res = await Swell.cart.update({
  billing:
    card: response.billing.
  },
}) as CartCamelCase

This would solve the issues. I also sent an example from your code that would probably fix the errors.

gusfune avatar Dec 30 '22 14:12 gusfune

I followed your hint and now works, but is ugly to override every single method. Hope to see a better implementation in the future.

artecoop avatar Dec 30 '22 14:12 artecoop

I followed your hint and now works, but is ugly to override every single method. Hope to see a better implementation in the future.

Glad that it worked! If you have any ideas on what we could do, let me know. Swell might take over the type maintenance sometime next year, so let's hope it's more seamless.

gusfune avatar Dec 30 '22 14:12 gusfune

I can update here that Swell has released typescript support and it's mostly functional as of 3.19.3. Some minor issues are listed on #81 but might be solved soon.

gusfune avatar Jan 12 '23 18:01 gusfune