Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I cast an object property in TypeScript?

Tags:

typescript

I have a simple issue, I'm using TypeScript with React and it works great so far, but I've run into this one little issue. I'm new to TypeScript but loving it so far, really reminds of Go

I'm trying to create a style and pass it into the style as an object e.g.

import * as React from 'react'
import * as ReactDOM from 'react-dom'

export interface NavbarProps {
  title: string;
}

export class Navbar extends React.Component<NavbarProps, undefined> {
  render() {
    return (
      <div style={styles.navbar}>
        <div style={styles.navbarTitle}>
          <h1 style={styles.navbarTitle}>{ this.props.title }</h1>
        </div>
      </div>
    )
  }
}

// Lets it compile properly
let spaceBetween: "space-between" = "space-between";

let styles = {
  navbar: {
    display: 'flex',
    flexDirection: 'row',
    paddingLeft: '10px',
    paddingRight: '10px',
    height: '50px',
    color: 'white',
    backgroundColor: "#333",
    alignItems: "center",
    justifyContent: spaceBetween
  },
  navbarTitle: {
    margin: 0,
    padding: 0,
    letterSpacing: "1px"
  }
};

if I remove the let spaceBetween: "space-between" = "space-between" and try to just do { justifyContent: "space-between" } I get an error because according to the typings for the CSSProperties Interface it declares justifyContent to be like this:

/**
         * Defines how the browser distributes space between and around flex items
         * along the main-axis of their container.
         */
        justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around";

so how can I inline the justifyContent rather than having to make a variable just for the casting.

Thanks.

Actual Error

src\public\views\components\navbar\navbar.tsx(11,12): error TS2322: Type '{ display: string; flexDirection: string; paddi
  Types of property 'justifyContent' are incompatible.
    Type 'string' is not assignable to type '"center" | "flex-start" | "flex-end" | "space-between" | "space-around"'.
like image 748
Datsik Avatar asked Dec 15 '16 12:12

Datsik


Video Answer


2 Answers

You have to specify the proper type for styles.navbar, something like

let styles = {
  navbar: {
    display: 'flex',
    flexDirection: 'row',
    paddingLeft: '10px',
    paddingRight: '10px',
    height: '50px',
    color: 'white',
    backgroundColor: "#333",
    alignItems: "center",
    justifyContent: "space-between"
  } as ViewStyle,  //<= here
...
}
like image 185
Bruno Grieder Avatar answered Oct 05 '22 05:10

Bruno Grieder


If you import React like this:

import * as React from "react"

You can do something like the followings:

let styles = {
    navbar: {
        display: 'flex',
        flexDirection: 'row',
        paddingLeft: '10px',
        paddingRight: '10px',
        height: '50px',
        color: 'white',
        backgroundColor: "#333",
        alignItems: "center",
        justifyContent: "space-between"
    } as React.CSSProperties
}

let styles: { [name: string]: React.CSSProperties } = {
    navbar: {
        display: 'flex',
        flexDirection: 'row',
        paddingLeft: '10px',
        paddingRight: '10px',
        height: '50px',
        color: 'white',
        backgroundColor: "#333",
        alignItems: "center",
        justifyContent: "space-between"
    }
}

let styles = {
    navbar: {
        display: 'flex',
        flexDirection: 'row' as "row",
        paddingLeft: '10px',
        paddingRight: '10px',
        height: '50px',
        color: 'white',
        backgroundColor: "#333",
        alignItems: "center" as "center",
        justifyContent: "space-between" as "space-between"
    }
}
like image 33
kimsk Avatar answered Oct 05 '22 07:10

kimsk