diary

主にコンピュータ技術関連のことを投稿。 / 投稿は個人の意見であり所属団体の立場を代表するものではありません。

Oculus Go で模様替えの計画を立てた

自分の部屋の模様替えを VR でプレビューしてみた。所要時間は休日1回分程度。想像以上に簡単で、みんなにも試して欲しいのでメモとして残しておく。

使う技術:

  • 100均で売ってるメジャー
  • DesignSpark Mechanical
  • Amazon Sumerian
  • Oculus Go

使ったお金:

  • メジャー: 108円
  • AWS 利用料金: 18円

必要な前提スキル:

  • なし

模様替え計画

部屋の様子および将来の予想図を作っておく。これには 3D モデリングツールが必要で、ラズパイでおなじみの RS Components が提供している DesignSpark Mechanical (無料)というやつが初心者に有用。Windows 専用なんだけど、持ってなければクラウドWindows サーバーでも使えばいい。

右側ペインのチュートリアルが親切で、3D モデリング未経験の私でも 30 分で何かしらの家具を作れるようになった。家具は箱型がベースだからどんどん作っていける。

とにかく家の中を 100均 で買ったメジャーで測りまくって再現した。といってもスムーズに行けば2時間かからないんじゃないかな。

f:id:ishn:20180605014618p:plain5.5畳くらいの tiny なアパートですが何か。

気が済んだら Room.obj として保存する。

f:id:ishn:20180605014630p:plain

すると、Room.mtl というのも作成される。

f:id:ishn:20180605014639p:plain

Amazon Sumerian にインポートする

Amazon Sumerian – VR アプリケーションや AR アプリケーションの構築

Amazon Sumerian ってご存知ない方も多いだろうけど、さっき作ったモデルを Oculus Go で見るために使う。習うより慣れろでとりあえずウェブのコンソールに入りましょう。

Amazon Sumerian - Pricing
AWS は有料だけど私の作成したやつの場合の今月の料金を試算したら 18円くらいだった。
  • シーンのサイズ: 14MB
  • ストレージ料金: 0.014GB * 0.06 USD = 0.00084 USD
  • 転送コスト: 0.014GB * 約30回 * 0.38 USD/GB = 0.1596 USD
  • 合計 0.16044 USD -> 18円くらい
アカウント作って1年以内の人は無料枠があるので 0 円。

AWS のコンソールは非常に多くのサービスがあって戸惑うかもしれないけど今は Sumerian にしか用はない。

f:id:ishn:20180605020434p:plainスクショには RAS症候群 が隠れていますね

入れたらおもむろに Create new scene

左下の Assets のところにさっきの Room.obj , Room.mtl二つとも一度にドラッグ&ドロップする。.mtl は色とか質感の情報が入っていて、これを一緒に入れないと全て灰色になってしまうのだが、後から個別にインポートすることができない。

f:id:ishn:20180605014644p:plain

アップロードが終わったら Assets 中の Room を中央のキャンバスエリアにまた D&D する。

するとマイホームが現れる。暗いのは光源がないから。後から入れるので大丈夫。

f:id:ishn:20180605014649p:plain

XYZ の軸が DesignSpark と異なるためひっくり返ってしまっている。左上側 Entities でさっき追加した Room が選択されていることを確認し、右側の Transform を次のように設定する。

f:id:ishn:20180605014653p:plain

中央上の Create Entity から pointlight を追加。矢印を引っ張って適当に配置。

f:id:ishn:20180605014701p:plain

VR のカメラを入れる。中央上の Import Assets から CoreVR を追加。

f:id:ishn:20180605014753p:plain

Assets にロードされたら、ツリーを辿って VRCameraRig を見つける。これをまたキャンバスに D&D 。

現時点で Entities はこんな感じになっているはず。

f:id:ishn:20180605014758p:plain

VRCameraRig を選択した状態で右側の VRCameraRig のうち CurrentCameraRig にチェックを入れる。

f:id:ishn:20180605014802p:plain

この辺りまでちょっとついて行けないという人はもう少し丁寧なステップがチュートリアルに載っているので参照してください。https://docs.sumerian.amazonaws.com/tutorials/create/beginner/getting-started-vr

VR カメラも移動する。Oculus Go を被る予定の位置にするのが没入感高くておすすめ。

f:id:ishn:20180605014824p:plain実はもうほぼ完成している。

左上のメニュー Scene -> Publish から Scene を公開する。この URL をメモしておく。

f:id:ishn:20180605014829p:plain

Oculus Go で体験する

さっきの URL をなんとかして Oculus Go に持っていく。自分は Google Keep を使った。

f:id:ishn:20180605014832p:plain

Oculus Browser で開くだけ。

f:id:ishn:20180605014835j:plain

右下のゴーグルアイコンから開始。

f:id:ishn:20180605014838j:plain

これで実際の家具を買う前に感覚を知ることができますね。すごい時代だ! f:id:ishn:20180605022318j:plain

(残念ながら Oculus Browser 経由の VR (WebVR) は録画できなかった。)

10年を振り返る

先日30歳の誕生日を迎え、今日は仕事納めです。思考の変遷を振り返ってみたい気持ちになりました。

20歳頃

まだ高校生だった気がします。その後ニートとフリーターを行ったり来たりで。

狂ったようにカラオケに行ったり、原付でツーリングに行ったりしても、「本当はこんなことやってる場合じゃない」という苦しい気持ちが常にありました。このままでは自分はダメなんだ、明日は正しいことをするんだ、と毎日思うものの、秋田の凍りつくような寒さと、時給600円の激安スーパー店レジバイトの前ではなんの役にも立たない決心でした。

弟が大学に落ちて予備校に行くというので、なんとか自分を変えようと思い同じ予備校へ入り、高校生に混じって勉強しました。

会津大学という超コスパのいいコンピュータ専門の単科大学があり、割と簡単かつ受験科目が少ないというので運よく潜り込めました。

23歳〜

もともと計算機と Linux が好きだったので1年目はチートできました。ただ、勉強習慣が無かったので数学系はどうやって単位を取ったのか覚えていないくらい身につきませんでした。さらに睡眠の習慣すら無かったので、人間関係とかソフトスキル的なものは破滅していたと思います。

この頃考えていたのは就職のことです。ワープワ脳なので3年目くらいまで本気で正規雇用をゴールにしていました。今思うと本当に低いハードル設定だと思うんですが、当時は東北近辺で中小企業に入れれば最高だな😸 と思っていました。

ただ、大学というのは自分にとっては蜘蛛の糸です。せっかくのチャンスだから会津大学でできることには全部関わろうと思いいろんなイベントに参加して活動しました。ハッカソンとか勉強会とか。あと大学周辺ベンチャーの Eyes, JAPAN という会社でバイトをして大変お世話になりました。その辺りで出会った人々から、コンピュータエンジニアとしての習慣を吸収しました。

就職時の年齢を気にしていたので飛び級制度を使い、学部3年+院2年で卒業することに決め、指導教員の先生のご指導のおかげでなんとか大学院に進めました。

26歳〜

コンピュータの動作原理を知っておきたかったので、奥山先生の研究室で回路設計を勉強しました。ただ、どういう技術トピックで他者と差別化するのかという考えばかりが強く、寄り道に多くの時間を使ってしまいました。

この頃考えていたのは「コンピュータエンジニアとして」どうするのか、という縛りでした。今思えば囚われ過ぎでしたが、ゴールも変わりました。就職を考える上でエンジニアとして社会とどう付き合っていくのかいうことです。

そこでエンジニアの働きは社会貢献に尽きるという信条を見出し、それを軸に仕事を探しました。新卒求人を始めたばかりのクラウドの会社があり、考え方が非常にマッチしていたので運よく拾っていただきました。

なんとか働いています。

社会人1年目は、睡眠とか勉強習慣とか、ツケにしていた問題が表面化していました。成果は出ないし体調は崩すしで、エンジニア云々以前の体のバグフィックスに時間を費やしました。

2年目になって気づいたのが、学生の時に必死になっていた技術的な知識の役の立たなさです。エンジニアの仕事は知識を持つことではなくて、問題を解決することです。これは技術の分野はあまり関係ないなと思いました。したがって、今はある程度専門性はあるものの固有の技術について固執していません。また、大学の頃のように、誰かの課題を解決できているわけではないのに表面的な雰囲気(githubとかね)を作ろうとするのはきっぱり辞めました。

そして昔と違って、これからどうなりたいのかはあまり思いつきません... まずはちゃんと人の役に立ちたいです。


そもそもなんでこの記事書いてるんでしょうね。とりあえず、自分の20歳の頃と似たような若者が居たら励ましたいです。こういう人の空白期間ってマジで空白ですからね。海外でバックパッカーとかしてたりしないですし。

振り返ってみると大きなステップを超えていくたびに考えていることがどんどん洗練されていくもんだなと感じます。20歳の自分のまま同じことを繰り返して歳を取っても、こうはならないと思います。

.styをTeX Liveに入れる方法(root不要)

ユーザ権限で行いたい。

この場合、~/texmfに置いておけば自動的に毎回読んでくれるらしい。

TeX Live - ArchWiki

たとえば CTAN: Package bytefield これを入れるときは、

$ mkdir ~/texmf
$ unzip bytefield.zip
(幸いこの中にはコンパイル済みの.styが入っていた)
$ cp -r tex/ ~/texmf
$ tree ~/texmf
/home/ishikuro/texmf/
└── tex
    └── latex
        └── bytefield
            └── bytefield.sty
(使えるかどうか確認)
$ kpsewhich bytefield.sty
/home/ishikuro/texmf/tex/latex/bytefield/bytefield.sty

あとはドキュメントに従って\usepackageなりするとよい。

pngとかjpgをplatexで使う(debian jessie)

注意: この方法でpngを貼ると、PostScriptプリンタでの印刷でとても時間がかかるようになる。パワポで作った図表はできればpdfで出力して貼り込むのがよいと思う。

$ sudo apt install texlive-lang-japanese latexmk

~/.latexmk

#!/usr/bin/perl
$latex         = 'platex %O %S';
$bibtex        = 'pbibtex %O %B';
$dvipdf        = 'dvipdfmx %O %S';
$pdf_mode      = 3; # use dvipdf
$pdf_previewer = "evince"

files:

main.tex
figure/
    a.png
    b.png

main.tex

...
\usepackage[dvipdfmx][graphicx]
\graphicspath{{./figure/}}
...


\begin{figure}
  \includegraphics{a.png}
\end

このままだとエラーになる

$ latexmk main.tex

runpopen command not allowed: extractbb

extractbbの許可

$ sudo cp /usr/share/texlive/texmf.cnf /etc/texmf/texmf.d/90extractbb.cnf

90extractbb.cnfにextractbbを追加

shell_escape_commands = extractbb,bibtex,bibtex8,kpsewhich,makeindex,mpost,repstopdf,
$ sudo update-texmf
$ latexmk main.tex

これで画像が自動で挿入される。いまどきはepsとか用意しなくていい。

WebからFPGAの回路を記述できる簡易IDEを作った

これはAizu Advent Calender 2015の21日目の記事です。
前は@yutoppさんです
次は@about_hiroppyさんの予定です。

はじめに

会津大学の学生のishikuroです。こんにちは。

需要がありそうだったので(確信)、育毛のプレゼンを書くつもりでしたが、今日12月21日は私の0x1C回目の誕生日であり、この先の一年の悪い暗示になってしまいそうなのと、優先的に紹介しないといけないものを思い出したのでやめます。育毛について聞きたい方は直接ご連絡ください。ちなみに誕生日についてはささやかなアピールです。

今日は「WebからFPGAの回路を記述できる簡易IDE」をyattan氏をはじめとした研究室のメンバーと一緒に作った経緯をお話しようと思います。

f:id:ishn:20151221174158g:plain


youtu.be

Webインターフェイスから回路を記述し、サーバーに接続されたFPGAボードに書き込みができます。

経緯

私の研究室では毎年グループワークの訓練も兼ねて、研究とは別に組み込みっぽい工作をしており、オープンキャンパスの日に研究成果と一緒に展示しています。

f:id:ishn:20151221162012p:plain
画像の出典: 研究室のpublicなサイト

今年の私の班は「高校生向けにコンピュータハードウェアの設計体験ワークショップを開く」というのに挑戦しました。私含め院2年生2名, 学部3年生4人で実行。



画像の下の方に見えてる工作も、ものすごいプロジェクトではあるんですが今回はチラ見せだけです。

このワークショップのオマケとして、ハードウェア記述言語のことも知ってもらえるかもしれないと思って作っていたものがあります。それが、ハードウェア記述言語のコンパイラおよびFPGA書き込みツールの、簡易IDEです。Arduino, ProcessingのIDEからインスパイアを受けてます。教育用として作りましたが、これが応用次第で「リモートからFPGAの回路を記述できるシステム」になるんです。

ishikuro/asolide · GitHub

githubに反映されてない部分もありますが、班内で分担して学部生も平等にコードを書きました。

ワークショップ当日は、来場者に論理ゲートの工作で4bit adderを作ってもらい動作を確認してもらいます。その後、工作と同じ内容のハードウェア記述を本IDEで実演し、同様な動作をすることを見てもらうつもりでした。しかし、演習内容を吟味した結果、来場者にとって詰め込みすぎになって疲れてしまうんではないかということが分かってきました。結局このシステムは当日は展示だけに留まっています。

機能

できること

NSLで回路を記述できる

世界で初めてハードウェア記述言語を提案したのは実は日本のNTT研究所でした。それまでは模造紙に論理を描いていたそうです。

今回のシステムでは国産ハードウェア記述言語の末裔、NSLを使っています。業界標準のVerilogHDLよりも抽象的に書けるのが利点です。

ちなみに今回のシステムに似たアイディアとして、NSLのオンラインコンパイラがあります。
NSL CORE TRIAL USE

このハードウェア記述言語で、GPIOの動作を記述していくことになります。

書き込みボタン以外なにもついてない

Altera等のFPGAメーカが提供するIDEEclipseよりも巨大で、周辺ツールが膨大になっています。しかし、そこから回路の論理設計のエッセンスだけを抽出したいと思い、ArduinoやProcessingのIDEのようなものを提案しました。書き込みボタンを押すと、回路設計のための様々なステップを隠蔽して、FPGAに書き込みをします。

FPGAではGPIOを制御

GPGPUのようなアクセラレータとしてFPGAを使う場合はPCIeとかに接続するのですが、今回はGPIOの操作だけを行えます。オンラインのArduinoみたいな感じです。

仕組み

Node.jsがメインのフレームワークです。

フロントエンド

入力したソースをサーバー側にPOSTして、コンパイルのログをsocket.ioで受け取ります。

複数ウィンドウを開いた状態で書き込みボタンを押すと、古いほうを中断してくれます。

バックエンド

以下のフローを子プロセスで実行します。

逐一、ログをフロントエンド側にsocket.ioで送ります。

FPGAの書き込みが終わったら、GPIOと記述した回路の動作が始まります。

未実装

今後の展望

XeonFPGAが載るなんて夢のある話もありますよね。きっと将来、AWS上でFPGAアクセラレーションがかけられるインスタンスも登場するんじゃないかと予想しています。

今回作ったやつは、書き込みこそUSB Blasterですが、実行時のFPGAとのインターフェイスはGPIOしかありません。サーバーとFPGAボードをPCIeと接続して、FPGAのリソーススケジューラみたいなのを実装すれば、もしかしたらクラウドFPGAの簡易的な実現と言えるかもしれません。

また、現在の構成だけでも、ArduinoのようなIoT的な使い方はできそうです。

余談ですが、いつかgithubのような場で回路関連のツールがどんどん出てくる時代になってほしいです。gemとかnpmみたいなコミュニティベースのエコシステムは一切ありえない回路設計業界ですが、オープンソースハードウェアの潮流がこちらに目を向けてくれたらと思ってます。

termdownでポモドーロテクニック

30分とか短時間で集中して作業するのが効果的らしい。まわりの人も結構やってたので私もやっている。termdownというツールが良かったので備忘録として書く。

ポモドーロテクニックとは - はてなキーワード

アジャイルな時間管理術 ポモドーロテクニック入門 | Staffan Noeteberg, 渋川 よしき, 渋川 あき | 本 | Amazon.co.jp

集中して仕事をこなすために、25分毎に時間を区切って仕事をする時間管理術。Francesco Cirillo氏が1992年、自身の勉強効率を上げるために考案した。

手順

1. 25分を1ポモドーロとし、やるべきタスクを1ポモドーロ刻み(25分毎)に分ける。
2. 25分間は、他の事は一切やらず、タスクに集中する
3. 25分経てば、5分間の休憩を入れる
4. 4ポモドーロ毎(2時間毎)に30分程の長い休憩をとる
5. 後は上記を繰り返す

ただし、いまいち良いアプリが無い。

欲しいキッチンタイマーアプリ:

  • 環境非依存
  • 変なイラストとかが入らない

探してみたところ、termdownというコマンドが要件を満たしていた。

インストール

python製であり、pipでインストールできる

sudo pip install termdown

使い方

termdown -a -b -c 10 --no-figlet 25m
  • -a, --alt-format: 付けないと、"24m 28s"みたいな表記になる
  • -b, --bliknk: 終了時目立つようにする
  • -c, --critical N: 最後のN秒を赤字にする
  • --no-figlet: デフォルトだとアスキーアートで表示されるのだが、場所をとるので表示しないようにできる

ターミナルのウィンドウを専有させて、文字サイズを大きめにし、Always on Topしておくと便利。

f:id:ishn:20151118104220p:plain

関連記事

ishikuro.hateblo.jp

React + TypeScript + Webpackの最小構成

このエントリは古い情報です。

今は typescript の代わりに flowtype も使えそうです。また、ブートストラップとしては create-react-app が提供されており、ここからカスタマイズしたほうが便利だと思います。

github.com


前回

ishikuro.hateblo.jp

の続き。前回のリポジトリを元にTypeScript版を作ってみたい:

GitHub - ishikuro/thinking-in-react-webpack-minimum at typescript

最終的なファイルツリー

.
├── dist
│   ├── bundle.js
│   └── index.html
├── package.json
├── README.md
├── src
│   ├── app.tsx
│   ├── tsd.json
│   └── typings
│       ├── react
│       │   └── react.d.ts
│       └── tsd.d.ts
├── tsconfig.json
└── webpack.config.js

今回もサーバーは立ち上げずにブラウザで直接ローカルのindex.htmlファイルを開いて動作を確認する。

前回と比較すると、型定義ファイル(typings/)とコンパイルオプション(tsconfig.json)が追加されている。

TypeScriptで記述

webpack中やvimプラグインで使われるので先にtypescriptのnpmを入れておく。

npm install -g typescript

.vimrc

" syntax highlightを有効にする
NeoBundle 'leafgarland/typescript-vim'
" typescriptのインデントを適切にする
NeoBundle 'jason0x43/vim-js-indent'
" コード補完や定義/参照へのジャンプをできるようにする
NeoBundle 'Quramy/tsuquyomi'
" .tsxもtypescriptとして扱う
autocmd BufNewFile,BufRead *.{ts,tsx} set filetype=typescript

型定義ファイルを追加

npm install -g tsd
cd src/
tsd query react --action install --resolve --save

コンパイル方法

TypeScript内でJSXやReactを扱うために、様々なハックが存在していたが、2015年7月ころにtypescriptがJSXをネイティブサポートしたために収束した。

  • typescript 1.6以上でコンパイルすればok, webpackで使う場合はnpm install --save-dev typescript@nextで入れる
  • 拡張子は.tsxにしておく
  • webpackでの利用方法や、Reactのコーディング方法はts-loaderのtestで提示されている。

babelの代わりにts-loaderを使う

npm install --save-dev typescript@next ts-loader

tsconfig.jsonを作成。(コンパイラオプションやリンカ的なものを指示するファイル)

{
  "compilerOptions": {
    "jsx": "react"
  },
  "files": [
    "src/typings/tsd.d.ts"
  ]
}

webpack.config.jsを更新。拡張子をtsxにして、ts-loaderを使うようにするだけ。(Option: コンパイル速度を上げるためにはexternal指定でreactをビルドに含めないようにする。html側で読み込む。参考: ReactとStylusをwebpackで使うための開発環境構築)

module.exports = {
  entry: [
    './src/app.tsx'
  ],
  output: {
    path: 'dist',
    filename: 'bundle.js'
  },
  resolve: {
    extensions: ['', '.tsx', '.ts', '.js']
  },
  externals: {
    react: 'React'
  },
  module: {
    loaders: [
      { test: /\.ts(x?)$/, loader: 'ts-loader' }
    ]
  }
};

(Option: dist/index.html reactを別ファイルで読み込む。)

<!DOCTYPE html>
<html>
  <head>
    <title>Thinking in React</title>
  </head>
  <body>
    <script src="../node_modules/react/dist/react-with-addons.min.js"></script>
    <script src="bundle.js"></script>
  </body>
</html>

src/app.tsxのサンプル。ポイントは、propsなどの受け渡しをinterfaceで行うこと。これだけでもだいぶ人に伝えやすくなると思った。

/// <reference path="typings/tsd.d.ts" />
import * as React from 'react';

interface Props {
  content: string;
}

class MyComponent extends React.Component<Props, {}> {
  render() {
    return <div>{this.props.content}</div>
  }
}

React.render(<MyComponent content="Hello World" />, document.body);

あとはコンパイルして確認

webpack
open dist/index.html

追記: ソースコードの変更点

全文はこちら: thinking-in-react-webpack-minimum/app.tsx at typescript · ishikuro/thinking-in-react-webpack-minimum · GitHub

import

/// <reference path="typings/tsd.d.ts" />
import * as React from 'react';

基本

interface PCRProps {
  category: string;
  key: string;
}

class ProductCategoryRow extends React.Component<PCRProps, {}> {
  render() {
    return (<tr><th colSpan={2}>{this.props.category}</th></tr>);
  }
}
  • propsやstateはinterfaceを作って明示する。extends React.Component<P, S>の形式でclassを作る。
  • JSXのプロパティも型があって、<th colSpan="2">もエラーになったので{2}としている。

ハマったところ

class SearchBar extends React.Component<SBProps, {}> {
  handleChange() {
    this.props.onUserInput(
        React.findDOMNode(this.refs.filterTextInput).value,
        React.findDOMNode(this.refs.inStockOnlyInput).checked
    );
  }

  render() {
    return (
      <form>
        <input
          type="text"
          placeholder="Search..."
          value={this.props.filterText}
          ref={"filterTextInput"}
          onChange={this.handleChange.bind(this)}
        />
        <p>
          <input
            type="checkbox"
            checked={this.props.inStockOnly}
            ref="inStockOnlyInput"
            onChange={this.handleChange.bind(this)}
          />
          {' '}
          Only show products in stock
        </p>
      </form>
    );
  }
}
  • React 0.13からDOMNodeの取得方法が変更になっている (React v0.13 - React Blog)
  • extends React.Componentから作る場合は、onChange={this.handleChange.bind(this)}のようにコールバックに.bindを自分で付けないとだめ

this.refsはランタイムで設定されるんだけど、TypeScriptコンパイラは分かってくれてないのでエラーを出す。

ERROR in ./src/app.tsx
(98,37): error TS2339: Property 'filterTextInput' does not exist on type '{ [key: strin
g]: Component<any, any>; }'.

ERROR in ./src/app.tsx
(98,54): error TS2339: Property 'value' does not exist on type 'Element'.

ERROR in ./src/app.tsx
(99,37): error TS2339: Property 'inStockOnlyInput' does not exist on type '{ [key: stri
ng]: Component<any, any>; }'.

ERROR in ./src/app.tsx
(99,55): error TS2339: Property 'checked' does not exist on type 'Element'.

解決方法は不明。一応、エラーを出しつつも.jsファイルは作ってくれて、意図した動作もするんだけど、とても嫌な感じ。

this.refsは使わないように、handleChange(e)から、e.target.valueみたいに取得する方針にして回避する。

Stateの初期化

interface FPTState {
  filterText: string;
  inStockOnly: boolean;
}

class FilterableProductTable extends React.Component<FPTProps, FPTState> {
  constructor(props) {
    super(props);
    this.state = {
      filterText: '',
      inStockOnly: false
    };
  }
...
  • getInitialStateはES6的な記述では使えない。代わりにconstructorを使う

JSONとかJSオブジェクトの読み込み

var PRODUCTS = [
  {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
  {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
  {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
  {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
  {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
  {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];

interface Product {
  category: string;
  price: string;
  stocked: boolean;
  name: string;
}

interface FPTProps {
  products: Product[];
}

React.render(<FilterableProductTable products={PRODUCTS} />, document.body);
  • そのままだとPropsに流し込めないので、一旦interfaceでラップする。