TypeScript2からのReactとnon-null assertion

TypeScript2からコンパイルオプションの strictNullChecks で、nullability をチェックできるようになった。
最近になってこのオプションを有効にしたら意外と修正するところが多かったのでメモ。

TypeScript1系の時は↓の様に書いてました。

import * as React from 'react'
import * as ReactDom from 'react-dom'

interface IAProps {
}
interface IAState {
  hoge?: string;
  fuga?: number;
}
class A extends React.Component<IAProps, IAState> {
  constructor(props: IAProps) {
    super(props);

    this.state = {
      hoge: '',
      fuga: 0
    }
  }

  render() {
    return(
      <B
        hoge={this.state.hoge}
        fuga={this.state.fuga}
      />
    );
  }
}

interface IBProps {
  hoge: string;
  fuga: number;
}
interface IBState {
}
class B extends React.Component<IBProps, IBState> {
  constructor(props: IBProps) {
    super(props);

    this.state = {
    }
  }

  render() {
    return(
      <div>
        {this.props.hoge}
        <br />
        {this.props.fuga}
      </div>
    );
  }
}

TypeScriptでstate管理するときは、毎回全部のパラメータを更新したいわけではないので

interface IAState {
  hoge?: string;
  fuga?: number;
}

という感じに? を付けてオプショナルにしていました。

そうすると、stateで管理しているhoge fugaの型が

hoge: string | undefined
fuga: number | undefined

と、それぞれ undefined になる可能性があるということになる。

Component B に値を渡すとき、Component B側では

interface IBProps {
  hoge: string;
  fuga: number;
}

というようにundefinedは許容されないので、

  render() {
    return(
      <B
        hoge={this.state.hoge!}
        fuga={this.state.fuga!}
      />
    );

!を付けて、non-nullであることを明示してあげないといけない。

最終的にソースコードはこうなりました。

import * as React from 'react'
import * as ReactDom from 'react-dom'

interface IAProps {
}
interface IAState {
  hoge?: string;
  fuga?: number;
}
class A extends React.Component<IAProps, IAState> {
  constructor(props: IAProps) {
    super(props);

    this.state = {
      hoge: '',
      fuga: 0
    }
  }

  render() {
    return(
      <B
        hoge={this.state.hoge!}
        fuga={this.state.fuga!}
      />
    );
  }
}

interface IBProps {
  hoge: string;
  fuga: number;
}
interface IBState {
}
class B extends React.Component<IBProps, IBState> {
  constructor(props: IBProps) {
    super(props);

    this.state = {
    }
  }

  render() {
    return(
      <div>
        {this.props.hoge}
        <br />
        {this.props.fuga}
      </div>
    );
  }
}

参考

15K 行のアプリを TypeScript 1.8 から 2.0 に移行してみた - はやくプログラムになりたい

go言語をインストールしてvimで保存時にコードフォーマットを走らせるまでの設定

Macの環境でgo言語をインストールして、vimソースコード保存時に自動でコードフォーマットが走るまでの環境設定です。

普段はIDEを使うので、vimでファイル保存時に go fmt を実行させる設定に手間取ってしまったのでメモしておきます。
vimプラグイン追加方法がわからなかっただけです。

go言語のインストール

$ brew install go

ここまでで、go言語を書いてコンパイルして実行まではできるようになります。

go言語は標準で go fmt でコード整形できるのですが、vimでファイル保存時に go fmt を実行して欲しいのでその設定方法についてです。

vimで go fmt するまでの設定

1. vim-plugをインストールする

$ curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

2. ~/.vimrcプラグインを読み込むようにする

~/.vimrc に下記3行を追加

call plug#begin('~/.vim/plugged')

Plug 'fatih/vim-go'

call plug#end()

3. vim をリロードして :PlugInstall を実行

ここまでの設定で vimでファイル保存時に自動で go fmt が実行されるようになります。

AWS CloudFormationでECSを管理するときにハマったこと

CloudFormationでECSを構築したときにハマったメモです。

CloudFormationのテンプレートを書いて

  • AWS::ECS::Cluster
  • AWS::ECS::Service
  • AWS::ECS::TaskDefinition

あたりの設定をして、構築しました。

動作確認ができたので、AWS::ECS::Service の設定を更新しました。
更新をしてみたところ、更新中のステータスから一向に進みませんでした。

テンプレートを確認すると、↓のようになっていました。
(下のテンプレートは余分な部分は書いてません)

  Service:
    Type: AWS::ECS::Service
    Properties:
      DeploymentConfiguration:
        MaximumPercent: 100
        MinimumHealthyPercent: 50

MaximumPercent: 100 ということで、新しいコンテナを追加できないのに追加しようとして動かない状態でした。 この状態だと、CloudFormationのタイムアウトを設定しないとずっと、更新中のステータスになってしまいます。

管理画面から手動でサービスの更新でタスク数を0にしてあげれば解決できました。

nodeのバージョン管理にnaveを使おうと思ったら上手くいかなかったのでメモ

basherからnaveをインストールしたあと、

$ nave use latest

を実行したところ、nodeのインストールに失敗した。

$ nave cache clear

したら直った

環境

AWS EC2 OS Debian Jessie AMI ami-dbc0bcbc

問題が発生した手順

  1. basherインストール
  2. naveインストール
  3. nodeインストール

basherのインストール

basherのInstallation手順に沿ってインストールした github.com

$ git clone https://github.com/basherpm/basher.git ~/.basher
$ echo 'export PATH="$HOME/.basher/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(basher init -)"' >> ~/.bash_profile
$ bash
$ basher update

naveインストール

naveのInstallation手順に従ってインストールした github.com

$ basher install isaacs/nave

nodeインストール(問題が起きたところ)

最新版のnodeを使おうと思い下記コマンドを実行した

$ nave use latest

コマンド結果

What version of node?
lts, lts/<name>, latest, x.y, or x.y.z >

ここで latest と入力してもnodeのインストールは実行されませんでした。

下記の通りキャッシュをクリアしたらインストールできました。

$ nave cache clear
$ nave use latest

MacにVisualStudio for Mac を入れてみたけど、dotnet coreが動かなかった

Macに VisualStudio for Mac を入れて、プロジェクトの作成から Console Application を選びました。

プロジェクトは作成されたのですが、リストア・ビルドが成功しませんでした。

$ which dotnet
dotnet not found

となり、どうやらdotnetコマンドが使えません。

SDKを入れ直してもダメでした。

調べてみると、シンボリックリンクが上手く晴れていないようなので

$ ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/

とすることで無事解決しました。

参考

github.com

AWS CloudFormationでインフラを構築するときに CAPABILITY_NAMED_IAM というエラーが出た

AWS CodePipeline + CloudFormation でインフラをソースコードで管理しようと思い、cfn-ci-cd-demo というRepositoryをベースにいろいろ試してみました。

github.com

IAM Role を作るときに、

Requires capabilities : [CAPABILITY_NAMED_IAM] 

というエラーが出ました。

エラーが出たときの手順

  1. src配下で、 IAM Role (RoleName指定有り)を作成するテンプレートを作成する
  2. git push してインフラ構築をする
  3. 1.で作成したテンプレートの構築時にエラーが出る

という流れで試していたので、1.の該当ファイルだけをCloudFormationのテンプレートに指定して動かしてみたところエラーも無く IAM Role の作成に成功しました。

cfn-ci-cd-demo では、

  1. ソースコード取得
  2. テスト
  3. ビルド
  4. 認証許可
  5. デプロイ

の手順で、デプロイ時に失敗するのでココに原因があるものだと思い、追加したファイルをいろいろ変更して試してみたのですがCodePipelineからのデプロイは成功しませんでした。

解決方法

ビルド時の Capabilities: CAPABILITY_IAM という設定が原因でした。

この部分です。

- Name: Build
  Actions:
    Configuration:
      Capabilities: CAPABILITY_IAM

IAM や IAM Role に名前を付けたい場合は CAPABILITY_NAMED_IAM にしないといけないようです。

公式のドキュメントにも書いてあることでした。

docs.aws.amazon.com

esaの任意ページを素早く表示するesajump公開しました。

Chrome Extensionで esajump というものを公開しました。 chrome.google.com

esajumpはドキュメント共有ツールにesaで、任意の番号のページを素早く表示することを目的としています。 esa.io

たまに、口頭で「esaの何番です」といった形で共有されるケースがあります。 そのときに

  1. esaのトップページを開く
  2. チーム名を指定する
  3. 適当なドキュメントを開く
  4. URLの番号を口頭で伝えられたものに書き換える

という感じで表示するまでが結構めんどくさかったりします。

esajumpは あらかじめチーム名を登録しておくことで、番号を入れるだけで該当のドキュメントを表示できるようになります。

使い方

ここでチーム名を入力し、Enterもしくは右にある + ボタンを押して登録します。
f:id:naught00:20170620222213p:plain
f:id:naught00:20170620222228p:plain

チーム名(hoge)が登録されました。
f:id:naught00:20170620222241p:plain

チーム名をクリックしたあとに表示される画面です。
ここで、背景グレーのテキストボックスに番号を入力しEnterを押すことで、新規タブで該当のドキュメントが表示されます。
チーム名をクリックした場合は、チームのREADMEが表示されます。
f:id:naught00:20170620222328p:plain

上図にある レンチマークのボタンを押したときに表示される画面です。
チーム名を誤って登録した場合はここから削除することができます。
f:id:naught00:20170620222343p:plain