michalochman / react-pixi-fiber

Write PixiJS applications using React declarative style.
MIT License
864 stars 94 forks source link

Text components style property is not correctly typed #311

Open zOadT opened 1 year ago

zOadT commented 1 year ago

Description

Since pixi.js 7.1 the type of Text.style is PIXI.TextStyle | Partial<PIXI.ITextStyle>. But pix-react-fiber only allows to set PIXI.TextStyle objects as style attribute (since 7.1 every property is required in PIXI.TextStyle)

Steps to reproduce

<Text
    text='Text'
    // Type '{ fontSize: number; }' is missing the following properties from type 'TextStyle': styleID, _align, _breakWords, _dropShadow, and 57 more.ts(2740)
    style={{
        fontSize: 64,
    }}
/>

Additional info

zOadT commented 1 year ago

I shortly looked into it: The problem seems to be that style has different types for the getter and setter:

// @pixi/text/lib/Text.d.ts
get style(): TextStyle;
set style(style: TextStyle | Partial<ITextStyle>);

There are Issues in the typescript repo that indicate that it is currently not possible to receive the type of the setters, so it seems like we have to manually adjust the type in our types :worried:

zOadT commented 1 year ago

In case someone else runs into this: As a workaround you can define a .d.ts file locally with the content

import type { IPointData, ITextStyle, TextStyle } from 'pixi.js'

declare module 'react-pixi-fiber' {
    interface PixiComponent<P = {}> {
        (props: Setters<PixiElement<P>>): React.ReactElement<P>;
    }

    type Override<P, E> = Omit<P, keyof E> & Partial<E>

    type Setters<P> = P extends Text
        ? Override<P, {
            text: string | number;
            style: TextStyle | Partial<ITextStyle>;
        }>
        : P extends TilingSprite
            ? Override<P, {
                tileScale: IPointData;
            }>
            : P;
}

Definitively not a clean solution, but I don't think we want explicit type information in the typings of this library.