Microsoft Teams Toolkit で TypeScript を使えるようにする
はじめに
前回の記事では Microsoft Teams Toolkit を使ってアプリを実行するまでの手順を確認しました。
記事中にも説明したとおり、Microsoft Teams Toolkit の既定の言語は JavaScript です。しかし、モダン開発をする上で TypeScript を使うことは必須とも言えます。そこで、Microsoft Teams Toolkit で作成したプロジェクトで TypeScript を扱えるようにする方法を解説します。
実行手順
拡張子の変更
JavaScript の拡張子である js ファイルを TypeScript のものに変更します。通常の TypeScript の拡張子は ts ですが、React の JSX を扱う場合の拡張子は tsx となります。以下のファイルの拡張子を変更します。
- src
- index.js -> index.tsx
- components
- App.js -> App.tsx
- Privacy.js -> Privacy.tsx
- Tab.js -> Tab.tsx
- TermsOfUse.js -> TermsOfUse.tsx
型定義パッケージのインストール
React の標準パッケージを型解決できるように型定義パッケージをインストールします。
- @types/react
- @types/react-dom
- @types/react-router-dom
npm install @types/react @types/react-dom @types/react-router-dom --save-dev
TypeScript のインストール
TypeScript のパッケージをインストールします。
- typescript
npm install typescript
TypeScript のトランスパイルには tsconfig.json が必要ですが、初回に npm run start したとき自動的に生成されるため、いったんはそのままで問題ありません。
Tab.tsx の修正
Tab.tsx が型解決できずエラーが発生するため修正します。
インターフェイスの追加
React のコンポーネントには Props と State がありますが、これをインターフェイスで定義します。
interface ITabProps { }
interface ITabState {
context: microsoftTeams.Context
}
クラス定義の修正
コンポーネントの継承をジェネリックになるように変更します。
class Tab extends React.Component<ITabProps, ITabState> {
...
}
コンストラクタの修正
コンストラクタでは型を指定するようにします。
constructor(props: ITabProps) {
super(props)
this.state = {
context: {} as microsoftTeams.Context
}
}
componentDidMount の修正
microsoftTeams.getContext のコールバックが定義と合わずにエラーが発生するため、パラメーターの error を削除します。
componentDidMount() {
microsoftTeams.getContext((context) => {
this.setState({
context: context
});
});
}
これで npm run start すればコンパイルが成功するはずです。
おわりに
最近の React はクラス コンポーネントではなく関数コンポーネントを使うことが一般的です。そのためすべて書き直すという方法もあります。書き直した場合、以下のようになります。
import React from 'react';
import './App.css';
import * as microsoftTeams from "@microsoft/teams-js";
const Tab: React.FC = () => {
const [context, setContext] = React.useState<microsoftTeams.Context>();
const [userName, setUserName] = React.useState<string>();
React.useEffect(() => {
microsoftTeams.getContext((value) => {
setContext(value);
});
}, []);
React.useEffect(() => {
if (context) {
setUserName(Object.keys(context).length > 0 ? context['upn'] : "");
}
}, [context]);
return (
<div>
<h3>Hello World!</h3>
<h1>Congratulations {userName}!</h1> <h3>This is the tab you made :-)</h3>
</div>
);
}
export default Tab;
Discussion