Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript React Native String literal assignment error

I have been getting a very strange error with regards to TypeScript telling me string literals do not match. (TypeScript v1.8)

import { Component } from "react";
import {
  StyleSheet,
  Text,
  View
} from "react-native";

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10,
  }
});

export class App extends Component<any, any> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
      </View>
    );
  }
}

Error:

src\client\index.ios.tsx(19,15): error TS2322: Type '{ fontSize: number; textAlign: string; margin: number; }' is not assignable to type 'TextStyle'.
  Types of property 'textAlign' are incompatible.
    Type 'string' is not assignable to type '"auto" | "left" | "right" | "center"'.
      Type 'string' is not assignable to type '"center"'.

I installed the correct typings. It seems that the following does not work in TypeScript.

interface Test {
  a: "p" | "q"
}

let x : Test;
let y = {
  a: "p"
}

x = y;

Source: https://blog.lopezjuri.com/2015/12/30/react-native--typescript/

like image 901
calclavia Avatar asked Jun 19 '16 22:06

calclavia


2 Answers

I know I'm late to the game, but just came across the same issue and prefer this solution (hate using 'any' since it kind of defeats the purpose of Typescript, although sometimes it's the only option):

import { Component } from "react";
import {
  StyleSheet,
  Text,
  View
} from "react-native";

interface Props { 
}

interface State {
}

interface Style { 
  container: React.ViewStyle,
  welcome: React.TextStyle
}

const styles = StyleSheet.create<Style>({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10,
  }
});

export class App extends Component<Props, State> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
      </View>
    );
  }
}

If we tell StyleSheet.create what type of styles to create the build error is resolved.

like image 181
Cailen Avatar answered Oct 20 '22 01:10

Cailen


sadly you need to assert the type:

<Text style={styles.welcome as any}>

Reason:

The type is inferred to based on declaraiton. A string literal is inferred as string (instead of string literal) because

let foo = "asdf"; // foo: string

// Its a string becuase: 
foo = "something else"; // Would be strange if this would error
like image 22
basarat Avatar answered Oct 19 '22 23:10

basarat