admin管理员组

文章数量:1291009

I am trying to understand how to merge declare an interface, but instead of adding a field to the interface itself, I wish to add a property to the object literal type.

I have a type defined in a library as follows:

interface DefaultSession {
    user?: {
      name?: string | null;
      email?: string | null;
      image?: string | null;
    };
    expires: ISODateString;
}

I know that if I wanted to add a field to this interface without changing the name, I could simply reopen and declare:

interface DefaultSession {
    role?: string
}

I have been studying the Typescript Handbook, but I can't find a way to merge declare role as a property under user to yield a type as follows:

interface DefaultSession {
    user?: {
        name?: string | null;
        email?: string | null;
        image?: string | null;
        role?: string | null;
    };
    expires: ISODateString;
}

I am trying to understand how to merge declare an interface, but instead of adding a field to the interface itself, I wish to add a property to the object literal type.

I have a type defined in a library as follows:

interface DefaultSession {
    user?: {
      name?: string | null;
      email?: string | null;
      image?: string | null;
    };
    expires: ISODateString;
}

I know that if I wanted to add a field to this interface without changing the name, I could simply reopen and declare:

interface DefaultSession {
    role?: string
}

I have been studying the Typescript Handbook, but I can't find a way to merge declare role as a property under user to yield a type as follows:

interface DefaultSession {
    user?: {
        name?: string | null;
        email?: string | null;
        image?: string | null;
        role?: string | null;
    };
    expires: ISODateString;
}
Share Improve this question edited Aug 5, 2022 at 5:36 Behemoth 9,3605 gold badges26 silver badges48 bronze badges asked Aug 5, 2022 at 4:28 Inda VidjoolInda Vidjool 3013 silver badges7 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

What you are looking for is intersection type:

https://www.typescriptlang/docs/handbook/unions-and-intersections.html

Just declare your custom type like following:

interface DefaultSession {
  user?: {
    name?: string | null;
    email?: string | null;
    image?: string | null;
  };
  expires: ISODateString;
}

type CustomDefaultSession = DefaultSession & {
  user?: {
    role?: string | null;
  }
}

Then you can use it like it is or implement it for your class. Besides if you want the same name for your custom type then just refer library type using alias.

If you have a callback inside library you can override argument type like the following:

// Callback defined inside the library.
type LibraryCallback = (defaultSession: DefaultSession) => void;

// Function inside the library which accepts callback.
function libraryFunction(libraryCallback: LibraryCallback): void
{
    // Do stuff...
}

// Application code which calls library function and changes callback argument type.
libraryFunction((customDefaultSession: CustomDefaultSession) =>
{
    const role = customDefaultSession.user.role;
});

Just do the following:

export interface Foo {
    user?: {
      name?: string | null;
      email?: string | null;
      image?: string | null;
    };
    expires: Date;
}


export interface Bar extends Foo {
  user?: Foo['user'] & {
    role?: string
  }
} 

First, extend the Bar form Foo and assign the user just like above with & sign. & merges two object types. Thus you get:

本文标签: