đź—“ August 8th, 2020
Â
In this post, I wanted to share what I’ve learned while tinkering with React Native TypeScript. Several things that we’ll be doing:
- Create React Native TypeScript project
- Adding a custom font to React Native application
- Make use of TypeScript’s
enum
feature to create aText
component
Create a React Native TypeScript project
To initiate this project, I used
npx
. The main reason I used npx
is I can execute any package directly from the npm
's registry without installing the package. The command that I use isnpx react-native init TILRNTypography --template react-native-template-typescript
The
--template react-native-template-typescript
flag will use React Native Community’s TypeScript template .When the app initiated, we’ll have project folder with this structure:
| __tests__
| android
| ios
|- app.json
|- App.tsx
|- babel.config.js
|- index.js
|- metro.config.js
|- package.json
|- ts.config.js
|- yarn.lock
Adding Font to React Native app
Download and save the font
In this project, I use Montserrat font. This font can be downloaded from Google Font. Before saving the font to this project, I created a new directory:
src/assets/fonts
. Then I save the font there. As a note, I only stored the variants that I’ll be using which are Regular
, SemiBold
, and Bold
. The new directory structure should be looked like this| __tests__
| android
| ios
| src
| | assets
| | fonts
| |- Montserrat-Bold.ttf
| |- Montserrat-Regular.ttf
| |- Montserrat-SemiBold.ttf
|- app.json
|- App.tsx
|- babel.config.js
|- index.js
|- metro.config.js
|- package.json
|- ts.config.js
|- yarn.lock
Â
Link the font
Then to make sure that the font can be used in our app, we have to link the font as the project assets. There are 2 ways to do this depending on the React Native version.
Version < 0.60
At these lines in the
package.json
{
...,
"rnpm": {
"assets": [
"./src/assets/fonts/"
]
}
}
Version >=0.60
Create a new file named
react-native.config.js
in the project’s root directory. Then fill the file with these linesmodule.exports = {
project: {
ios: {},
android: {}
},
assets: ["./src/assets/fonts/"]
}
Run the link
Link the asset using this command
npx react-native link
Â
This command will link the fonts that we stored in
./src/assets/fonts
to the Info.plist
in the ios/{project_name}
for iOS and create a new directory in ./android/app/src/main/assets/fonts
for Android.At this phase, the fonts are ready to use using
fontFamily
attribute. For instance<Text style={{ fontFamily: 'Montserrat-Regular' }}>Contoh</Text>
Make use of TypeScript’s enum
feature to create Text
component
We will create a
Text
component that will accept the text’s type as a prop. In this case, I define 3 types of Text
: H1
, H2
, and Paragraph
. There are a lot of ways to do this, but in this post, I’ll use enum
.Text
component
The first step is to create a file called
Component__Text.tsx
in the new directory called ./src/components
.| __tests__
| android
| ios
| src
| | assets
| | | fonts
| | |- Montserrat-Bold.ttf
| | |- Montserrat-Regular.ttf
| | |- Montserrat-SemiBold.ttf
| | components
| | |- Component__Text.tsx
|- app.json
|- App.tsx
|- babel.config.js
|- index.js
|- metro.config.js
|- package.json
|- ts.config.js
|- yarn.lock
First, import the needed modules in the
Component__Text.tsx
// Component__Text.tsx
import React from 'react';
import {Text, StyleSheet} from 'react-native';
Then, define the text’s types in
enum
, let’s called it TextType
. I export the TextType
to make sure it’s available to another module that will use this component.// Component__Text.tsx
// ...
export enum TextType {
H1,
H2,
Paragraph,
}
After that, we create a
style
for each type of text that already defined// Component__Text.tsx
// ...
const STYLES = StyleSheet.create({
H1: {
fontSize: 30,
fontFamily: 'Montserrat-Bold',
},
H2: {
fontSize: 20,
fontFamily: 'Montserrat-Semibold',
},
Paragraph: {
fontSize: 14,
fontFamily: 'Montserrat-Regular',
},
});
Then, create the Text component with its
props
' type
. The component will use the type
prop to create its style.// Component__Text.tsx
// ...
type TComponent__TextProps = {
type?: TextType;
children: string;
};
const Component__Text = (props: TComponent__TextProps) => {
const makeStyle = () => {
switch (props.type) {
case TextType.H1:
return STYLES.H1;
case TextType.H2:
return STYLES.H2;
case TextType.Paragraph:
default:
return STYLES.Paragrah;
}
};
return <Text style={makeStyle()}>{props.children}</Text>;
};
export default Component__Text;
The complete code for
Text
component should looks like this// Component__Text.tsx
import React from 'react';
import {Text, StyleSheet} from 'react-native';
export enum TextType {
H1,
H2,
Paragraph,
}
type TComponent__TextProps = {
type?: TextType;
children: string;
};
const Component__Text = (props: TComponent__TextProps) => {
const makeStyle = () => {
switch (props.type) {
case TextType.H1:
return STYLES.H1;
case TextType.H2:
return STYLES.H2;
case TextType.Paragraph:
default:
return STYLES.Paragrah;
}
};
return <Text style={makeStyle()}>{props.children}</Text>;
};
export default Component__Text;
Â
Using the Text
component
Import the
Text
component that we’ve created to the App.tsx
// App.tsx
import React from 'react';
import {SafeAreaView, StyleSheet} from 'react-native';
// Import the Text component
import Text, {TextType} from './src/components/Component__Text';
Then, use the component with its various styles
// App.tsx
const STYLES = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
const App = () => {
return (
<>
<SafeAreaView style={STYLES.container}>
<Text type={TextType.H1}>Heading</Text>
<Text type={TextType.H2}>Heading 2</Text>
<Text type={TextType.Paragraph}>Ini contoh body</Text>
</SafeAreaView>
</>
);
};
export default App;
The complete code for
App.tsx
should looks like this// App.tsx
import React from 'react';
import {SafeAreaView, StyleSheet} from 'react-native';
// Import the Text component
import Text, {TextType} from './src/components/Component__Text';
const STYLES = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
const App = () => {
return (
<>
<SafeAreaView style={STYLES.container}>
<Text type={TextType.H1}>Heading</Text>
<Text type={TextType.H2}>Heading 2</Text>
<Text type={TextType.Paragraph}>Ini contoh body</Text>
</SafeAreaView>
</>
);
};
export default App;
If everything is working correctly, we should see this in the app

Phew, I think that’s all. Thank you for reading through this post!
Cheers and happy coding! ✌️💻