react-native and typescript 的一個style問題


react-native and typescript

以下react-native的代碼,將樣式都提取出來使用StyleSheet.create創建的話是這樣:

import * as React from 'react';
import { AppRegistry, View ,StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    backgroundColor: '#F5FCFF',
  }
});

class AlignItemsBasics extends React.Component{
  render() {
    return (
      <View style={styles.container}></View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);

這在.js環境中是沒有問題,但是要加入typescript就會有點小問題了。使用的@types版本為:

"@types/react": "^15.0.16",
"@types/react-native": "^0.42.5",

現在先用typescript重寫:

import * as React from 'react';
import { AppRegistry, View ,StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    backgroundColor: '#F5FCFF',
  }
});

class AlignItemsBasics extends React.Component<any , any>{
  render() {
    return (
      <View style={styles.container}></View>
    );
  }
};

AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);

這個時候會報:
Type '{ flex: number; flexDirection: string; justifyContent: string; backgroundColor: string; }' is not assignable to type 'ViewStyle'.
styles.container的type跟ViewStyle不匹配。有興趣的可以去@type/react-native里看下ViewStyle的定義。這里說結論是,問題是出在flexDirection和justifyContent中這兩個屬性中,這兩個屬性是使用String Literal Types定義的。然后TS中像這樣使用是識別不出來的:

interface Test {
  a: "p" | "q"
}
let x : Test;
let y = {
  a: "p"
}
x = y;//Type '{ a: string; }' is not assignable to type 'Test'

然后要解決這個問題可以斷言:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    backgroundColor: '#F5FCFF',
  } as ViewStyle
});

更好的方法是用范型聲明style的類型:

import * as React from 'react'
import {View , Text , StyleSheet,ViewStyle ,TextStyle} from 'react-native'

export default function setup(){
  return class SampleTS extends React.Component<any,any> {
    render() {
      return (
        <View style={styles.container}>
          <Text>Hello world</Text>
        </View>
      );
    }
  }
}

interface Style {
  container: ViewStyle,
  welcome: TextStyle
}

const styles = StyleSheet.create<Style>({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  }
});


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM