简体   繁体   中英

Unable to declare multiple custom named properties TypeScript MUI v5 Palette

I am trying to setup many custom attributes to keep things semantically easy to update in the future. However I am having issues with having more than just one custom property in MUI v5

Ts Error

TS2717: Subsequent property declarations must have the same type. Property 'background' must be of type 'TypeBackground', but here has type 'PaletteColor'.

palette.ts

export const palette = {
  primary: {
    light: '#6D6B8C',
    main: '#6514DD',
    dark: '#6D6B8C',
  },
  secondary: {
    main: '#6D6B8C',
  },
  error: {
    main: '#bd4646',
  },
  background: {
    main: '#fff',
    paper: '#F5F5F5',
  },
  border: {
    main: '#DADAE1',
    primary: '#DADAE1',
  },
  text: {
    primary: '#6D6B8C',
    secondary: '#000',
  },
}


declare module '@mui/material/styles' {
  interface Palette {
    border: Palette['primary']
    background: Palette['primary']
  }

  // allow configuration using `createTheme`
  interface PaletteOptions {
    border?: PaletteOptions['primary']
    background?: PaletteOptions['primary']
  }
}

在此处输入图像描述

You're using a feature of TypeScript called declaration merging . The problem is because non-function members of the interfaces should be unique. If they are not unique, they must be of the same type (see docs here ).

A quick aside: Using declare module 'foo' to import and merge existing objects is called module augmentation , which is a special type of declaration merging. You can actually merge two interfaces with the same name in the same file.


A Possible Solution

Since it's not possible to merge two members of different types with declaration merging, an alternative could be to simply declare a new type.

/// animal.ts
export interface Animal {
  name: string
  age: number
  birthday: string // goal: represent birthday as a `Date` instead of `string`
}


/// pet.ts
import { Animal } from './animal'

// remove the offending property from `Animal`, while simultaneously
// extending the new `Pet` type to add `birthday` back in as a `Date`
type Pet = Omit<Animal, 'birthday'> & {
  birthday: Date
  ownerId: number
}

// the compiler accepts the augmented definition of `Pet`
const pet: Pet = {
  name: 'fido',
  age: 2,
  birthday: new Date(), // see, not a string!
  ownerId: 1
}

Explanation

Since declare module adds extra noise, I'll leave it out to make the example more intuitive. Consider the following code snippet:

/// animal.ts - good
export interface Animal {
  name: string
  age: number
}

export interface Animal {
  birthday: string
}

The above code is completely allowed in TypeScript. The compiler merges the two separate declarations of Animal into a single definition.

Let's look at a different example.

/// animal.ts - bad
export interface Animal {
  name: string
  age: number
  birthday: string
}

export interface Animal {
  birthday: Date
}

Hopefully, the problem is obvious. Both declarations of Animal have birthday , but of different types. How is the compiler supposed to know what type birthday should be? It could make some assumptions, but thankfully it does't, instead preferring to give an error:

typescript: Subsequent property declarations must have the same type. Property 'birthday' must be of type 'string', but here has type 'Date'.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM