reactjs - Typescript-feil under inline fontWeight-stil i React


Jeg prøver å implementere denne CSS-regelen på en td

const boldText = {
    fontWeight: 'bold'
}

<td style={boldText}>Content</td>

Men det gir følgende feil:

[ts]
Type '{ style: { fontWeight: string; }; children: string; }' is not assignable to type 'DetailedHTMLProps<TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement>'.
  Type '{ style: { fontWeight: string; }; children: string; }' is not assignable to type 'TdHTMLAttributes<HTMLTableDataCellElement>'.
    Types of property 'style' are incompatible.
      Type '{ fontWeight: string; }' is not assignable to type 'CSSProperties'.
        Types of property 'fontWeight' are incompatible.
          Type 'string' is not assignable to type '"bold" | "initial" | "inherit" | "unset" | "normal" | "bolder" | "lighter" | 100 | 200 | 300 | 40...'.

Svar #1

Typescript kan være utrolig dumt noen ganger. Det antar typen til fontWeight som en streng, selv om det kunne snevret det ned til den eksakte litteralen. Du kan bare kaste det som seg selv for å fikse dette:

const boldText = {
    fontWeight: 'bold' as 'bold'
}

<td style={boldText}>Content</td>

I dag kan du også bruke den nye as const-erklæringen på slutten av dine litteraler for samme effekt:

const boldText = {
    fontWeight: 'bold'
} as const;

<td style={boldText}>Content</td>

Og til slutt kan du alltid spesifisere en eksplisitt type for objektet når du erklærer det:

const boldText: React.CSSProperties = {
    fontWeight: "bold"
};

<td style={boldText}>Content</td>

Svar #2

Typescript ser boldText som et "vanlig" objekt, og antar derfor boldText.fontWeight som streng:

const boldText = {
    fontWeight: 'bold' // <-- TS doesn't know more than this is a string
}

Koden <td style={boldText}>Content</td> forventer CSSProperties, så en streng kan ikke tildeles.

For å løse misforholdet, kan du fortelle Typescript typen til objektet:

const boldText: CSSProperties = {
    fontWeight: 'bold'
}

For å være mer presis:

  • f.eks. color: '#ff0000' ville fungere, fordi color aksepterer verdier av typen string.
  • fontWeight: 'bold' fungerer ikke, selv om fontWeight aksepterer "bold", fordi TS bestemmer seg for å bruke typen string før det vet om konteksten til CSS, og typen string er ikke det samme som typen "bold" | "bolder" | 100 | 200 | ...:
const boldText = {
    fontWeight: 'bold'  // <-- TS makes it's decision for type 'string'
    color: '#ff0000'    // <-- TS makes it's decision for type 'string'
}

// TS doesn't complain about color, as color accepts NamedColor | string | ...
// TS only complains about fontWeight, as it accepts only "bold" | "bolder" | 100 | 200 | ...
const TD = <td style={boldText}>Content</td>

Relaterte artikler