からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

Microsoft Teams Toolkit で TypeScript を使えるようにする

前回の記事では Microsoft Teams Toolkit を使ってアプリを実行するまでの手順を確認しました。

blog.karamem0.dev

記事中にも説明した通り、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 が型解決できずにエラーになるので修正します。

interface の追加

React のコンポーネントには PropsState がありますがこれを interface で定義します。

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;