讀書不覺已春深 !明日清明節
在使用Typescript編寫程序RN過程中遇到困擾,且不論react,不論在瀏覽器中,只論寫react-native
的APP,怎麼使用 declare聲明文件 和 namespace命名空間編寫滿意的程序。
因不能在網上找到合適的資源,以至於寫該博客準備了久久近2周。
在編寫Typescript語言下的react-native時,拋出 3 個問題
1,rn 中怎麼使用第三方Javascript開源庫 ?
2,rn 中怎麼使用 global全局變量 ?
3,rn 中怎麼使用自己本地編寫的Javascript ?
react-native 中安裝並使用Javascript開源庫 react-native-ui-lib
安裝該UI庫 react-native-ui-lib,需要安裝相應的上述依賴
npm i react-native-ui-lib
@react-native-community/blur
@react-native-community/netinfo
@react-native-community/datetimepicker
react-native-reanimated
安裝成功之後,在文檔中會看到只能使用在Javascript語言的react-native中。能使用在Typescript語言中, 有爲該開源庫編寫**.d.ts
聲明文件。然後使用時會報找不到No overload matches this call.
但是由於該開源庫已經具有聲明文件,所以時可以使用的。
爲換一種方式使用,以方便描述怎麼在本地編寫聲明文件。我在本地爲組件重新編寫了聲明組件,詳情解析請點擊下一篇
接下來要使用 react-native-ui-lib
就需要爲其手動編寫聲明文件了。網絡上有很多關於Jquery的聲明文件編寫。但不是應用在react-native中,且無法貼切表達rn中應如何的編寫與使用聲明文件,畢竟環境不同,畢竟本人不太專業Web端 。故此,研究了好久終有所突破並於此分享出來~
按照文檔編寫下方js文件
// */libs/components/FoundationConfig.js (第一步)
import {Colors, Typography, Spacings} from 'react-native-ui-lib';
Colors.loadColors({
primaryColor: '#2364AA',
secondaryColor: '#81C3D7',
textColor: '##221D23',
errorColor: '#E63B2E',
successColor: '#ADC76F',
warnColor: '##FF963C'
});
Typography.loadTypographies({
heading: {fontSize: 36, fontWeight: '600'},
subheading: {fontSize: 28, fontWeight: '500'},
body: {fontSize: 18, fontWeight: '400'},
});
Spacings.loadSpacings({
page: 20,
card: 12,
gridGutter: 16
});
// */libs/components/ComponentsConfig.js (第二步)
import {ThemeManager} from 'react-native-ui-lib';
// with plain object
ThemeManager.setComponentTheme('Card', {
borderRadius: 8
});
// with a dynamic function
ThemeManager.setComponentTheme('Button', (props, context) => {
// 'square' is not an original Button prop, but a custom prop that can
// be used to create different variations of buttons in your app
if (props.square) {
return {
borderRadius: 0
};
}
});
// */libs/components/MyScreen.js (第三步)
import React, {Component} from 'react';
import {View, Text, Card, Button} from 'react-native-ui-lib';
class MyScreen extends Component {
render() {
return (
<View flex padding-page>
<Text heading marginB-s4>My Screen</Text>
<Card height={100} center padding-card marginB-s4>
<Text body>This is an example card </Text>
</Card>
<Button label="Button" body bg-primaryColor square></Button>
</View>
);
}
}
export default MyScreen;
使用重點,編寫以下 聲明文件
// */libs/components/MyScreen.d.js (第四步:創建聲明文件提供 *.tsx 使用)
import React, {Component} from 'react';
declare class MyScreen extends Component {}
export default MyScreen;
在react-native中的*.tsx
文件中,使用已聲明過的Javascript文件
//第五步 *.tsx 文件中使用Javascript程序
// */screens/OnlineContact.tsx
import React from 'react';
import {
StyleSheet,
View,
Text,
Image,
} from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import DeviceConfs from '../confs/DeviceConfs';
import ImgConfs from '../../src/confs/ImgConfs';
import StringChecker from '../libs/js-module/jsmodule';
import MyScreen from '../libs/components/MyScreen';
interface OnlineContactProps {
id: string;
schecker: StringChecker;
}
interface OnlineContactState {
tabIndex: number;
}
export default class OnlineContact extends React.Component<OnlineContactProps, OnlineContactState>{
schecker = new StringChecker();
constructor(props: OnlineContactProps){
super(props);
this.state = {
tabIndex: 0
}
}
render(){
return <View style={{flex:1, alignItems:'center', backgroundColor: 'white'}}>
{/* 標題欄 */}
<View style={{width: DeviceConfs.sWidth, height: 42,
flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<TouchableOpacity onPress={()=>{this.props.navigation.pop()}} activeOpacity = {0.8}
style={{flexDirection:'row', alignItems: 'center', width:DeviceConfs.sWidth * 0.3}}>
<Image source={ImgConfs.ic_goback} resizeMode={'contain'}
style={{width: 38, height: 38}}/>
<Text style={{color: '#444', fontWeight: 'bold', fontSize: 14, alignSelf: 'center', marginLeft: -6}}>{'返回'}</Text>
</TouchableOpacity>
<View style={{width:DeviceConfs.sWidth * 0.3, alignItems: 'center', justifyContent:'center'}}>
<Text style={{color: '#333', fontWeight: 'bold', fontSize: 18}}>{'TS功能測試'}</Text>
</View>
<View style={{width:DeviceConfs.sWidth * 0.3}}/>
</View>
<View style={{height:4, width: DeviceConfs.sWidth, backgroundColor: '#f4f4f4'}}/>
{/* 寫入測試的代碼 */}
{/* 自定義聲明文件使用第三方庫的js */}
<View style= {{width:DeviceConfs.sWidth, height: DeviceConfs.sHeight ,
padding: 30 ,justifyContent: 'center'}}>
<MyScreen />
</View>
</View>
}
}
效果展示
react-native 中使用 global全局變量
Javascript中的RN有使用 global全局變量的方式,當然Typescript的RN也有自己使用global全局變量的方式 。
Javascript語言中的全局變量配置方式
Typescript語言下的全局配置,則需要通過編寫聲明文件*.d.ts
使用到全局變量的擴展方式。比如一下擴展全局變量手機尺寸,寬和高。
// */types/index.d.ts
// Prop Types
export {};
declare global {
var gHeight: string | number;
var gWidth: string | number;
}
export {}; 此行代碼必不可少,使當前全局聲明成爲module聲明。
聲明文件書寫完畢之後,聲明文件中是不允許具體實現的。所以需要對在新聲明的全局變量在APP起始頁進行賦值。
// */AppContainer.tsx (APP起始頁.tsx的組件容器)
const sWidth = Dimensions.get('window').width;
const sHeight = Dimensions.get('window').height;
class AppContainer extends React.Component<AppProps> {
constructor(props: AppProps){
super(props);
//配置全局變量-初始化
gHeight = sHeight;
gWidth = sWidth;
}
... ...
應用到頁面中,比如 .tsx 測試頁面
// */screens/OnlineContact.tsx
import React from 'react';
import {
View,
Text,
Image,
} from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import DeviceConfs from '../confs/DeviceConfs';
import ImgConfs from '../../src/confs/ImgConfs';
import StringChecker from '../libs/js-module/jsmodule';
interface OnlineContactProps {
id: string;
schecker: StringChecker;
}
interface OnlineContactState {
tabIndex: number;
}
export default class OnlineContact extends React.Component<OnlineContactProps, OnlineContactState>{
schecker = new StringChecker();
constructor(props: OnlineContactProps){
super(props);
this.state = {
tabIndex: 0
}
}
render(){
return <View style={{flex:1, alignItems:'center', backgroundColor: 'white'}}>
{/* 標題欄 */}
<View style={{width: DeviceConfs.sWidth, height: 42,
flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<TouchableOpacity onPress={()=>{this.props.navigation.pop()}} activeOpacity = {0.8}
style={{flexDirection:'row', alignItems: 'center', width:DeviceConfs.sWidth * 0.3}}>
<Image source={ImgConfs.ic_goback} resizeMode={'contain'}
style={{width: 38, height: 38}}/>
<Text style={{color: '#444', fontWeight: 'bold', fontSize: 14, alignSelf: 'center', marginLeft: -6}}>{'返回'}</Text>
</TouchableOpacity>
<View style={{width:DeviceConfs.sWidth * 0.3, alignItems: 'center', justifyContent:'center'}}>
<Text style={{color: '#333', fontWeight: 'bold', fontSize: 18}}>{'TS功能測試'}</Text>
</View>
<View style={{width:DeviceConfs.sWidth * 0.3}}/>
</View>
<View style={{height:4, width: DeviceConfs.sWidth, backgroundColor: '#f4f4f4'}}/>
{/* 寫入測試的代碼 */}
{/* 自定義聲明文件擴展全局變量 */}
<View style= {{width:DeviceConfs.sWidth, height: DeviceConfs.sHeight ,
padding: 30 ,alignItems: 'center'}}>
<Text style={{fontSize: 16, color: 'red', alignSelf: 'flex-start'}}>
{'自寫聲明文件 擴展全局變量:'}{'\n'}{'手機高度:'}{gHeight}{'\n手機寬度:'}{gWidth}
</Text>
</View>
</View>
}
}
效果展示
react-native使用自編寫的Javascript文件
舉例兩種 —— class類的文件、variable和function的文件
編寫本地的Javascript文件 —— 類class
// */namesp/ZipCodeValidator.js
// const numberRegexp = /^[0-9]+$/;
export default class ZipCodeValidator {
isAcceptable(s) {
return "ZipCodeValidator - 使用export namespace 聲明文件";
}
}
// */namesp/ZipCodeValidator.js
import ZipCodeValidator from "./ZipCodeValidator";
// const lettersRegexp = /^[A-Za-z]+$/;
class LettersOnlyValidator {
isAcceptable(s) {
return "LettersOnlyValidator - 使用export namespace 聲明文件";
}
}
LettersOnlyValidator.ZipCodeValidator = ZipCodeValidator;
export default LettersOnlyValidator;
編寫聲明文件,爲提供給 Ts
使用
// */namesp/LettersOnlyValidator.d.ts
declare class LettersOnlyValidator{
isAcceptable(s?: string): string;
}
declare namespace LettersOnlyValidator {
export class ZipCodeValidator{
isAcceptable(s?: string): string|boolean;
}
}
export default LettersOnlyValidator;
*.tsx
文件中使用Javascript文件
// */screens/OnlineContact.tsx
import React from 'react';
import {
View,
Text,
Image,
} from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import DeviceConfs from '../confs/DeviceConfs';
import ImgConfs from '../../src/confs/ImgConfs';
import StringChecker from '../libs/js-module/jsmodule';
import LettersOnlyValidator from '../libs/namesp/LettersOnlyValidator';
interface OnlineContactProps {
id: string;
schecker: StringChecker;
}
interface OnlineContactState {
tabIndex: number;
}
export default class OnlineContact extends React.Component<OnlineContactProps, OnlineContactState>{
schecker = new StringChecker();
constructor(props: OnlineContactProps){
super(props);
this.state = {
tabIndex: 0
}
}
render(){
return <View style={{flex:1, alignItems:'center', backgroundColor: 'white'}}>
{/* 標題欄 */}
<View style={{width: DeviceConfs.sWidth, height: 42,
flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<TouchableOpacity onPress={()=>{this.props.navigation.pop()}} activeOpacity = {0.8}
style={{flexDirection:'row', alignItems: 'center', width:DeviceConfs.sWidth * 0.3}}>
<Image source={ImgConfs.ic_goback} resizeMode={'contain'}
style={{width: 38, height: 38}}/>
<Text style={{color: '#444', fontWeight: 'bold', fontSize: 14, alignSelf: 'center', marginLeft: -6}}>{'返回'}</Text>
</TouchableOpacity>
<View style={{width:DeviceConfs.sWidth * 0.3, alignItems: 'center', justifyContent:'center'}}>
<Text style={{color: '#333', fontWeight: 'bold', fontSize: 18}}>{'TS功能測試'}</Text>
</View>
<View style={{width:DeviceConfs.sWidth * 0.3}}/>
</View>
<View style={{height:4, width: DeviceConfs.sWidth, backgroundColor: '#f4f4f4'}}/>
{/* 寫入測試的代碼 */}
{/* 自定義聲明文件使用本地js */}
<View style= {{width:DeviceConfs.sWidth, height: DeviceConfs.sHeight ,
padding: 30 ,alignItems: 'center'}}>
<Text style={{fontSize: 16, color: 'red', alignSelf: 'flex-start'}}>
{'自寫聲明文件 使用本地編寫的Javascript:'}{'\n'}{new LettersOnlyValidator.ZipCodeValidator().isAcceptable()}
</Text>
</View>
</View>
}
}
效果展示
編寫本地的Javascript文件 —— variable和function
// */js-module/jsvariable.js
export const httpurl = 'https://www.baidu.com/';
export function watchTV(){
console.log('我在看電視 呢?!');
let status = '給我把電視 打開 ~';
return status;
}
編寫聲明文件,爲提供給 Ts
使用
// */js-module/jsvariable.d.ts
declare const httpurl: string;
declare function watchTV(): string;
export {httpurl, watchTV}
*.tsx
文件中使用Javascript文件
// */screens/OnlineContact.tsx
import React from 'react';
import {
View,
Text,
Image,
} from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import DeviceConfs from '../confs/DeviceConfs';
import ImgConfs from '../../src/confs/ImgConfs';
import StringChecker from '../libs/js-module/jsmodule';
import LettersOnlyValidator from '../libs/namesp/LettersOnlyValidator';
import {httpurl, watchTV} from '../libs/js-module/jsvariable';
interface OnlineContactProps {
id: string;
schecker: StringChecker;
}
interface OnlineContactState {
tabIndex: number;
}
export default class OnlineContact extends React.Component<OnlineContactProps, OnlineContactState>{
schecker = new StringChecker();
constructor(props: OnlineContactProps){
super(props);
this.state = {
tabIndex: 0
}
}
render(){
return <View style={{flex:1, alignItems:'center', backgroundColor: 'white'}}>
{/* 標題欄 */}
<View style={{width: DeviceConfs.sWidth, height: 42,
flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<TouchableOpacity onPress={()=>{this.props.navigation.pop()}} activeOpacity = {0.8}
style={{flexDirection:'row', alignItems: 'center', width:DeviceConfs.sWidth * 0.3}}>
<Image source={ImgConfs.ic_goback} resizeMode={'contain'}
style={{width: 38, height: 38}}/>
<Text style={{color: '#444', fontWeight: 'bold', fontSize: 14, alignSelf: 'center', marginLeft: -6}}>{'返回'}</Text>
</TouchableOpacity>
<View style={{width:DeviceConfs.sWidth * 0.3, alignItems: 'center', justifyContent:'center'}}>
<Text style={{color: '#333', fontWeight: 'bold', fontSize: 18}}>{'TS功能測試'}</Text>
</View>
<View style={{width:DeviceConfs.sWidth * 0.3}}/>
</View>
<View style={{height:4, width: DeviceConfs.sWidth, backgroundColor: '#f4f4f4'}}/>
{/* 寫入測試的代碼 */}
{/* 自定義聲明文件使用本地js */}
<View style= {{width:DeviceConfs.sWidth, height: DeviceConfs.sHeight ,
padding: 30 ,alignItems: 'center'}}>
<Text style={{fontSize: 16, color: 'red', alignSelf: 'flex-start'}}>
{'自寫聲明文件 使用本地編寫的Javascript:'}{'\n'}{httpurl}{'\n'}{watchTV()}
</Text>
</View>
</View>
}
}
效果展示
後續有關聲明文件的如何編寫,請點擊下一篇 ~
文章參考:
https://ts.xcatliu.com/basics/declaration-files
https://zhongsp.gitbooks.io/typescript