szebert
szebert

Reputation: 55

How to assign a property a type inside an object constant in TypeScript?

Learning TypeScript and I'm wondering if there's an easy in-line way to signify the type inside an object constant when TypeScript doesn't infer the property type correctly?

Error Message:

Type '{ align: string; fontWeight: string; dropShadow: boolean; dropShadowAlpha: number; wordWrap: boolean; fill: string[]; }' is not assignable to type 'TextStyle | Partial<ITextStyle> | undefined'.
  Type '{ align: string; fontWeight: string; dropShadow: boolean; dropShadowAlpha: number; wordWrap: boolean; fill: string[]; }' is not assignable to type 'Partial<ITextStyle>'.
    Types of property 'align' are incompatible.
      Type 'string' is not assignable to type 'TextStyleAlign | undefined'.ts(2322)

Got this error message before I replaced the original align and fontWeight values with textStyleAlign and textStyleFontWeight.

How I created this example:

yarn create react-app app-name --template typescript
cd app-name
yarn add pixi.js
yarn add @inlet/react-pixi

App.tsx

import { Stage, Text} from '@inlet/react-pixi';
import type { TextStyleAlign, TextStyleFontWeight } from '@pixi/text';

const textStyleAlign : TextStyleAlign = 'center';
const textStyleFontWeight : TextStyleFontWeight = '900';

const textStyle = {
  align: textStyleAlign,
  // align: 'center',   // <- why can't I put this instead?
  fontWeight: textStyleFontWeight,
  // fontWeight: '900', // <- same here
  dropShadow: true,
  dropShadowAlpha: 0.6,
  wordWrap: true,
  fill: ["white", "#cccccc"]
}

function App() {
  return (
    <Stage>
      <Text
        text={`Hi World`}
        style={textStyle}
      />
    </Stage>
  );
}

export default App;

Upvotes: 1

Views: 850

Answers (2)

jean182
jean182

Reputation: 3505

Hey by taking a look at the docs you need to pass a TextStyle instance like this:

const textStyle = new TextStyle({
  align: "center",
  fontWeight: "900",
  dropShadow: true,
  dropShadowAlpha: 0.6,
  wordWrap: true,
  fill: ["white", "#cccccc"]
});

If you don't want to create that instance you can do this:

import { ITextStyle, TextStyle } from "pixi.js";

// The style prop also takes a Partial of ITextStyle so by typing the const like that you would achieve the typing correctly
const textStyle: Partial<ITextStyle> = {
  align: "center",
  fontWeight: "900",
  dropShadow: true,
  dropShadowAlpha: 0.6,
  wordWrap: true,
  fill: ["white", "#cccccc"]
};

If you want to make it like the code you posted then you can use the as type assertion like this

const textStyle = {
  align: "center" as TextStyleAlign,
  fontWeight: "900" as TextStyleFontWeight,
  dropShadow: true,
  dropShadowAlpha: 0.6,
  wordWrap: true,
  fill: ["white", "#cccccc"]
};

If you pass any of those 3 methods you won't have type problems:

<Text text="Hi World" style={textStyle} />

I noticed that by checking the style prop o the Text component:

style?: TextStyle | Partial<ITextStyle> | undefined

So basically all the typing done above will work.

Check this sandbox to look the functional code: https://codesandbox.io/s/elastic-platform-zzvnb

Upvotes: 0

Viet
Viet

Reputation: 12787

Because align has only three type: 'left', 'center' or 'right': https://pixijs.download/dev/docs/PIXI.TextStyle.html#align

So if you want to use align, you need to make sure it has these types. Not string with value center. You can use TextStyleAlign to declare the type as you do. Or const textStyleAlign : 'center' = 'center';.

If you don't want declare type like this. You can use new TextStyle(): https://reactpixi.org/components/text

style={
  new TextStyle({
    align: 'center',
    ...
  })
}

Upvotes: 1

Related Questions