Search code examples
typescriptnext-auth

Type 'string' is not assignable to type 'SessionStrategy | undefined'


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


Solution

  • 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' }