Home > Net >  Type 'string' is not assignable to type 'SessionStrategy | undefined'
Type 'string' is not assignable to type 'SessionStrategy | undefined'

Time:10-30

I am use next-auth for authorization in next project and use typescript, when I assign 'jwt' to strategy, a warn for type error occur: Type 'string' is not assignable to type 'SessionStrategy | undefined'.

my code:

  session: {
    strategy: 'jwt',
  },

type code: these type are all the official type, no declare by myself

export interface NextAuthOptions {
...
session?: Partial<SessionOptions>;
...
}
type Partial<T> = { [P in keyof T]?: T[P] | undefined; }
export interface SessionOptions {
...
strategy: SessionStrategy;
...
}
export declare type SessionStrategy = "jwt" | "database";

enter image description here

CodePudding user response:

TLDR;

Add a type to the options object:

export const authOptions: NextAuthOptions = {

Explanation:

Imagine you have a function:

type GreetOptions = {
  greeting: 'hello' | 'hey'
  name: string
}

const greet = ({ greeting, name }: GreetOptions) => {
  console.log(`${greeting}, ${name}!`)
}

You could call it directly like:

greet({ greeting: 'hello', name: 'Joe' })

But then if you extract object to a variable, it fails...

const options = { greeting: 'hello', name: 'Joe' }

// ERROR! Type 'string' is not assignable to type '"hello" | "hey"'.(2345)
greet(options)

The compiler reads through the code in the same order that it would execute. So it first encounters the options variable. It doesn't read ahead in the code to try to figure out what you're going to do with it, it just infers a reasonable type for it:

const options: {
  greeting: string;
  name: string;
}

Then when you try to pass that to greet, the string type for greeting is not specific enough to match the argument type. However, you can help it out and declare what it should be:

const options: GreetOptions = { greeting: 'hello', name: 'Joe' }

And now it can check it and make sure that you don't do:

const options: GreetOptions = { greeting: 'goodbye', name: 'Joe' }

CodePudding user response:

I have solved the warn of type: some telled me that 'jwt' just a string type by typescript view, so it could be anything that is a sting type, let's say 'foo' are also string type, so I can't assign it to a variable that's expecting a SessionStrategy, since SessionStrategy can only be "jwt" | "database"

session: {
    strategy: 'jwt' as const,
},

should solve it,so TS doesn't turn "jwt" into string and stays narrowed to "jwt".

when this type warn disappear, I encounter another type warn:

Argument of type '{ providers: (OAuthConfig<GoogleProfile> | OAuthConfig<GithubProfile>)[]; adapter: Adapter; callbacks: { session: ({ session, token }: { ...; }) => Promise<...>; jwt: ({ user, token }: { ...; }) => Promise<...>; }; session: { ...; }; }' is not assignable to parameter of type 'NextAuthOptions'.
  The types of 'callbacks.jwt' are incompatible between these types.
    Type '({ user, token }: { user: any; token: any; }) => Promise<any>' is not assignable to type '(params: { token: JWT; user?: User | undefined; account?: Account | undefined; profile?: Profile | undefined; isNewUser?: boolean | undefined; }) => Awaitable<JWT>'.
      Types of parameters '__0' and 'params' are incompatible.
        Type '{ token: JWT; user?: User | undefined; account?: Account | undefined; profile?: Profile | undefined; isNewUser?: boolean | undefined; }' is not assignable to type '{ user: any; token: any; }'.
          Property 'user' is optional in type '{ token: JWT; user?: User | undefined; account?: Account | undefined; profile?: Profile | undefined; isNewUser?: boolean | undefined; }' but required in type '{ user: any; token: any; }'.ts(2345)

and fix it with:

import type { User } from 'next-auth';
import { JWT } from 'next-auth/jwt';

jwt: async ({ user, token }: { user?: User | undefined; token: JWT }) => {
      if (user) {
        token.uid = user.id;
      }
      return token;
    },

the final code as the picture: enter image description here

  • Related