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