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,
}
});