t_hazawaの日記

株式投資とWebエンジニアリングのブログです。株式投資の目次は→です。 https://t-hazawa.hatenablog.com/entry/2021/02/12/220933

AWS CDKを修正して実行できるようになった

これはアドカレの記事です

  • これは ドワンゴのカレンダー | Advent Calendar 2022 - Qiita 14日目の記事です。
  • なお、25日目にも記事を投稿予定です。(Qiitaで)
    • こちらは、大トリにふさわしく、(インパクトのある)高クオリティな記事にしようと思っているので、期待していてください。
  • (= つまり、今回の記事のクオリティは高くない…が、(クオリティが低くても)継続が大事 なのでありのままのやり方で、いつもどおり書いてます)
  • この記事は 25000文字あります (文庫本50ページ分)

経緯・背景

  • (2021/8/23 までに、CloudFormation をとりあえず書いて使えるようになっていた)
  • 2022/8/2までに RubyGems (HTML文字列をいい感じにフォーマットする) を公開した
  • 元々、2022/9/30までに以下の3つが目標だった
    • RubyGems を公開する
    • (業務で使う) AWS CDKを修正して、実行できるようになる
    • TypeScriptを少しでも業務のプロダクトに組み込む
  • しかし、結婚式をしたので、RubyGems以外は完遂できなかった (それぞれ半分くらい?)
    • 結婚式の後も、新婚旅行と上期の評価資料作りで忙しかった
  • 2022/8/23 に CDK に手を付けていたが9/3頃?に中断し、 2022/10/8 に再開した。
  • 2022/11/2 までに、 CDK を修正して、実行(反映)できるところまで行った
  • その後、社内のLTの準備をしていて、今日(2022/11/26) このCDKのブログを書き始めた。
    • 2022/12/12 出来上がった。(19300字)

(CDKに関して)やったこと

  • CDKのことを学ぶ
  • 業務のCDKを読む
  • 業務のCDKを自分のAWSアカウントで実行する (一部分のStackだけ)
  • そのStackを一部CDKで変更してみる

CDKのことを学ぶ編

  • 5分で理解するAWS CDK - Qiita
  • CDKはただリソースを定義するだけでなく、プログラム内でテストコードも書くこともできます。

  • CDKは以下、APP->Stack->Constructの各要素によって構成されています。

  • ↓ということらしい
    • App スタック依存関係管理
    • Stack いつもの
    • Consruct リソース
  • CDKはConstruct Libraryを使用してAWSリソースを定義

  • High Level Construct(L2) - > 直感的にリソースを定義することができ、デフォルト値や便利なメソッドが定義済み

  • クラス名にCfnプレフィックスがついているL1 (L1の方が低レイヤー)
  • cdk synth シンセサイザーというか、組み合わせるといういみ
  • なお、aws ssoを利用している環境の場合、そのまま実行すると、エラーになります。確認すると、本記事執筆時点ではAWS SSOについてサポートされてない様です。この様な場合、環境変数をexportすることで回避できます。

  • 親切な情報
  • CDKの本質は抽象化です。抽象化によってAWSの深い知識がなくてもクラウドインフラの構築が行えます。

  • 理想はこのようになることみたい

業務のCDKのコードを読んで理解

  • それぞれにREADME.md があって親切
  • 公式手順(ちょっと大変みたい…?)
  • iam identity centerは、コードを使用してiam identity centerセッションを現在のaws cliセッションに関連付けます

  • iam identity centerブラウザページでは、iam identity centerの認証情報を使用してサインインするように求められます

  • そういうブラウザページがあるのね 2022/08/24 0:41
    • この↑までは「自動設定」だったとのこと
  • 手動設定でもできるとのこと

業務のCDKのコードを読む

  • 反映コマンドなどがREADMEに(各スタックごとに)書いてあって分かりやすい!
  • 業務のCDKは codefamily, db, elasticache, network, subnet, vpc, web スタックに分かれており、 共通みたいなのがcommon, utility に入っている
  • SFTP = SSH File Transer Protocol 2022/08/25 0:04
  • SFTPStack AWS Transfer Familyを使用してS3バケットをバックエンドにしたSFTPサーバを立てるSTACK

  • s3を保存先にしたftpサーバを立ててくれるaws transfer familyというサービス

CDKのコマンドなど

いきなり業務のCDKコードを(自分の個人AWSアカウントで)実行するのは難しかったので、0からCDKを書いて、実行してみた (ような気がしていたが、していなかった) (3ヶ月前にやったことなので忘れていた)

  • ec2のなかに CfnVPC作るメソッドがあるおなじみのec2起源なつくり
  • ipamもこのメソッドにあるのね
  • class CfnVPC (construct) · AWS CDK
  • ◎この(業務で使ってる)CDKのバージョンはなんなんだろうなあ
    • 現行最新なら 2.38.1かな?
    • aws-cdk-lib==2.XX.X と requirements.txt にあった
    • $ cdk --version #2.XX.X (build xxxxxxx)
  • 名前とかを渡すと vpc が作れる便利なメソッド
  • 自分の aws で作ってみたいね
  • vpc/vpc_stack.py は単なるクラス、汎用に流用できるものっぽい
    • …と思ったけど、そうでもないかな◎
  • .bat って rem がコメントアウトなの?
    • そうらしい
  • こうやって、 vpc, network をカワキリに、業務のCDKを読んでいったのだった
  • ◎network ではなく、 vpc/ や subnet/ でつくってる、ってことかな? 2022/08/28 1:08
  • やっぱり yml だけで作るのは無理感が高いよなあ(CloudFormationへの思い)
  • 自分も別プロジェクトで cFn でsubnet とか作ったので見覚えある内容 というか構成
  • でもやっぱり CDKとかにしてくと、サワれる人 どんどん少なくなって、採用がどんどん困難になっていきそう

CDKのことを十分には知ってなかったので更に知る編

cdk の construct とは

  • cdk のconstruct ってなんだっけ?
  • AWS CDK の3種類の Construct を使ってデプロイしてみた | DevelopersIO
  • サンプルコードもあるので、熟練者のcdkがどんなものか見ようかな
  • いろんなものが一緒に書かれていた あくまでこの記事の目的のためのサンプルっぽい
    • (多分普通は vpc とか subnet とか web(アプリケーション構成単位)で分けそう)
  • construct は デプロイするAWSリソース。 だね。 (解決) ココのリソース
  • ec2.CfnSubnet(
    • やっぱり ec2 以下にサブネット作るメソッドもあるのだった
    • 基本的なものは何でもec2のものとするaws
  • cdkわかりやすい
  • network周り長い 2022/08/28 1:46 要素が多い
    • cFnのときより心なしか増えてる気がする
  • NAT GW で使う eip

業務のcdkを引き続き読む (/common 編)

  • まぁ、 common/ みる 2022/08/29 0:42
  • aws kms = Key management service (かなり使いそう)
  • kubernetes は eks (そっくり)
  • XRegionParam はオリジナルclass だった ので後で読もう
  • common_stack.py で 5つ stack class 定義シてる
  • Acm とか、自分のawsで実行しても既に取られてるから実行できないかもなあ
  • xregion 先に読もうか
  • custom resource
  • [AWS CDK] APIを呼び出すだけのカスタムリソースならLambda関数は不要な件 | DevelopersIO
  • AWS CDKの場合、Lambda関数を使わずにAPIを呼び出してカスタムリソースを作成/更新/削除することができます。

  • 皆さんはカスタムリソースを作成することは多いですか? 私はそこまで多くないです。

  • 内部的にはaws sdkを実行するためのlambda関数が自動で作成される。

  • codecommitの承認ルールテンプレート関連の操作はcloudformationで実装されていません。。。そこで、今回はcodecommitに関する以下の操作をカスタムリソースを介して行います。

  • ◎なるほど、こういうやり方があるのね 共有したい
  • なお、actionで入力する文字列の先頭は大文字ではなく、小文字の場合で入力する必要がある場合がほとんどです。例えば、CreateApprovalRuleTemplate APIを呼び出したい場合は、createApprovalRuleTemplateとなります。

  • ☆複雑なlambda 関数が自動で作られて便利 2022/08/29 1:11 (まとめ)
  • これで「わざわざLambda関数作るのめんどくさいな」からちょっと脱出することができます。

  • サーバーレスからLambda関数レスヘ 2022/08/29 1:11
  • なお、APIを呼び出す前に処理を入れたり、複数のAPIを呼び出す場合はLambda関数を介してカスタムリソースを作成する必要があります。

  • x_region_param は、 SSM とかの値を他のregion でも取ってこれるようにしてるようだ

SSM (AWS Systems Manager)とは

  • AWS Systems Manager とは? - AWS Systems Manager
  • AWSの新サービス SSM を知っていますか? | DevelopersIO (2015/3)
    • simple なやつらしい
    • ssmはamazon ec2 simple systems managerの略で、windowsの構成管理を行えるサービスです。 awswindows用のchef serverやpuppet masterを提供してくれる様なものです

    • なんか違う感
  • AWS Systems Manager の方らしい
  • Systems Manager で↓ができるらしい 2022/08/30 0:12
    • アプリケーション管理
    • 変更管理
    • ノード管理
    • オペレーション管理
    • Quick Setup
    • 共有リソース
  • systems manager の aws ドキュメントよんだ2022/08/30 0:17
  • ASM と SECRETSMANAGER にも対応している、作ってもらった x_region_param (便利メソッド)
    • CDKでもお手製便利メソッドが出てくる

ASM (Amazon Secrets Manager) とは

  • AWS Secrets Managerを使おう! - Qiita
  • aws secretsmanager get-secret-value --region ${REGION} --secret-id ${SECRETS_ID}

  • みたことあるコマンド
  • x_region_param 読み切った 2022/08/30 0:29
  • 引き続き行むのCDK読んでく common/
  • common_stack.py がある
  • 井かの5つのスタックをたててる
    • ACM
    • ACM APNE1
    • KeyPair
    • KMS
    • WAFV2
  • WAFv2 に IP Address tai書かれてる
  • common/ はよみきった

(業務のCDKの) utility/ 編

(業務のCDKの) web/ 編

  • webサーバ周り
  • EC2 だけでなく、 ALBとか CloudFront とかも一緒に入ってるメインのスタック
  • アプリケーション上の役割別に 7つStackがある
  • Backend ヨウのStack は 1つの Class から 複数Stack を作ってる
  • config に色々と設定値がかかれてるっぽい auto scaling group のmax capacity とか
  • asg.add_user_data( にコマンドで、最初にやることを列挙できて便利
  • backend_stack.py と front_stack.py に分かれてる
  • class Duration · AWS CDK
    • 期間を表すらしい 2022/09/01 0:21
  • ec2も少ないパラメータでできるね
  • ☆wafもきになるなあ 2022/09/01 0:34
  • utcCoordinated Universal Time

ついに自分のAWSアカウントで実行してみるぞ

  • (結局、CDKを0から書くことはしなかった模様)
  • 一旦、 vpc を実行 & vpc を修正できたらよしにしようかな
    • ということで、業務のCDKの vpcのところを自分のAWSアカウントでやってみることに
  • 多分、aws-cli で操作するのだろう (←違う。cdkコマンドをnpmで入れて使う)
    • cdk は aws-cli のコマンド? 調べる 2022/10/08 21:18

cdkを動かすための勉強

クラメソさんの連載1回めを読む

  • まぁせっかくだから ↓の連載を 4までは読んでみようか
  • 実践!AWS CDK #1 導入 | DevelopersIO
  • summit-online-japan-cdk をやって、環境を整えるのが第一らしい 2022/10/08 21:34
  • 実践!AWS CDK #1 導入 | DevelopersIO にkaiteannように、cdk は npm で入れる aws-cdk パッケージで入るコマンドだった 2022/10/08 21:40
  • $ npm install @aws-cdk/aws-ec2
    • 今後もこのように利用するクラスによって必要なパッケージをインストールしていきます。

  • なるほどなあ
  • ここに記載されているリソースが次の cdk deploy コマンドで AWS クラウド上に構築されることになります

  • cdk bootstrap コマンドとか いろいろある ←cfnのためのs3作る
  • いよいよデプロイです。cdk deploy コマンドを実行します。

  • vpc をつくったらデフォルトでは たくさん色々作られるらしい
  • Construct という単位の基本ビルディングブロック - 作られる各リソースのことだったね

  • L3: Patterns

  • これハツみみ
  • cdkでは各リソースを表すクラスにcfnというプレフィックスが付いたl1のものが用意されています このクラスを利用することでcfnと同等の制御が可能となります。

  • NAT ゲートウェイは比較的料金がかかるサービス 。スタックを削除するには cdk destroy コマンドを実行します。

  • README にも記載していますが node_modules/ は git 管理外としていますので、プロジェクトを実行する際は npm install コマンドを実行して必要なモジュールをインストールしてください。

クラメソさんの連載2-4回めを読む

  • 実践!AWS CDK #2 VPC | DevelopersIO
  • 普通の構成を作るのに 20買いくらいかかるとのこと
    • 20 回くらいかかるかもね。
  • まぁ 4買い読んで 実行してみようとして できなかったらさらに読もうかなあ
  • devio-stg-vpc 10.0.0.0/16

  • リソース名は弊社の命名規則 システム名-環境名-AWS リソース名

  • それでは cdk synth コマンドを使用すると cfn のテンプレートがつくられる  2022/10/11 1:28

  • 実践!AWS CDK #3 テスト | DevelopersIO

  • snapshot tests。。テスト実行時点で作成されるcfnテンプレート(スナップショット)と事前に保存されているベースラインテンプレートを比較してテスト

  • jest を使うのね (TSだからかな)
  • Ansible のときは「Ansibleに書いたのはそのように作られるのだから、ちゃんとできているかテストは不要よ」みたいなことをどこかで読んだ気がするけど、 でもやっぱり 1個アレができてるか とか書いておくと、意図通りになってるか確認できてよいね

  • 実践!AWS CDK #4 Context | DevelopersIO

  • context は cfnのパラメータ

元やってたことに戻る

  • まぁ、何してたのか思い出そう
    • cdk が何のコマンドか調べていたのだった
    • (業務のCDKのコードの) vpc の readme を読んでてたのだった

業務のCDKのReadme に書いてあるコマンドを理解する

  • cdk context --clear とは?
  • Concepts - Context|AWS CDK ドキュメント(和訳メモ) を読んでみる
  • 少しずつ実際の実行に近づいていってる
  • cdkは、アカウント内のavailability zoneやインスタンスの起動に使用されるamazon machine image(ami)idなど、awsアカウントからの情報をキャッシュするためにコンテキストを使用します - パラメータトイウだけでなく、キャッシュでもあるのね - だから clear が必要と

  • このプラクティスは、例えば、新しいamazon linux amiがリリースされ、auto scalingグループが変更されたときに、デプロイメントへの予期しない変更を回避します。 - 途中で変わってしまわないようにという意味もキャッシュにあるのね

  • cdk.context.jsonは、gitにコミットすることをお勧めします

  • コンテキスト値は、それを作成したコンストラクトにスコープされ、子コンストラクトからは見えますが、兄弟コンストラクトからは見えません。 - どこかで出てきそう

Python の None の勉強

  • python には none というものがあるのね
  • 【Python入門】nullオブジェクト「None」とは | 侍エンジニアブログ
  • Pythonでは他のプログラミング言語とは少し違い、nullというキーワードではなく「None」を使用します。 - > ※ この記事のコードはPython 3.7で動作確認しました。

  • オブジェクトとnoneを比較する場合は、is演算子を使用することが推奨されています。。。理由は、処理が早く済むことや、noneがシングルトンオブジェクト(そのクラスのオブジェクトは1つのみ、複数のインスタンスの作成が不可能であること)である、などということが挙げられます

  • None を print すると None と表示するのが律儀な感じ2022/10/12 23:24
    • 他の言語だったら空文字列になりそう

元のzen (cdk context --clear) に戻る

  • AWS CDK アプリと呼ぶのね CDKで書いたものを
  • cdk.context.json ファイル内の情報を表示、管理するには、cdk context コマンドを使用します - ◎そのうち cdk context コマンド使ってみよう 2022/10/12 23:29

  • 保存されているアプリのコンテキスト値をすべてクリアするには、次のようにcdk context --clearを実行します。 - こういうことね (理解できたので目的達成) - > cdk.context.jsonに格納されているコンテキスト値のみ、リセットまたはクリアすることができます。

  • 必要であれば、コンテキスト値の前にスタック名を付けることで、各スタックに異なる値を指定することができます。 - > cdk synth --context Stack1:key=value --context Stack2:key=value Stack1 Stack2

  • zen を 読み切った 2022/10/14 0:19 3min

元の 業務のcdk vpc readme に戻る

派生して cdk コマンドの コマンドを一通り知る

CDK バージョンのこと

本当に cdk のコマンドを知ってく

  • ls は Stack をリストするらしい
  • アプリケーションが単一のスタックだけで構成されている場合、スタック名を指定する必要はありません

  • cdk.json または ~/.cdk.json のいずれかが存在する場合、そこに指定されたオプションがデフォルトとして使用されます

  • コミットされてる cdk.jsonにも contextがあるね
    • main/vpc/cdk.json
    • IPAMPool とかもここにあるね
  • コマンドに node packageを指定する
    • --plugin , -pなんてオプションがあるのね
  • オプションはそこそこ多いけど、 コマンド自体は少なそう cdk
  • cdk.json に "app": "npx ts-node bin/eval-cdk.ts" があると --app指定は要らないとのこと
    • 業務のでも "app": "python app.py", 普通にあった (main/vpc/cdk.json)
    • main/vpc/app.py のことだね

tree コマンドのこと

もとに戻って cdk のコマンド(派生1)を読むぞ 2022/10/15 7:46

  • cdk bootstrap がなんかdeploy 前にいるらしい 2022/10/15 7:48
    • aws にアクセスして整えるらしい
    • 実際にこれをしたところ、 cdk bootstrap しただけで、 cdk 用 S3バケットや、 cloudformation の cdk 実行用 stack ができたりした
  • cdk コマンドの機能を 実際に叩いて理解する 【 AWS CDK Command Line Interface 】 | DevelopersIO を読んでいるところだった
  • cdk diff もあって便利 2022/10/15 22:24
  • lib:constructsの集まりをnpmなどで公開可能なように開発できます

  • 3つのリソースから構成される AWS Construct Library - そういうのを配布できるらしい 2022/10/15 22:41

  • Apps と AWS Construct Library をうまく組み合わせる

  • cdk.context.json がデプロイときに自動で書き込まれるやつ、 cdk.json が開発者が書くやつ
    • .cdk.json かも??? つかない気がするけど
  • context 直下の値が Key として認識されていて、それより下層はすべて Value として扱われるようです。

  • cdk diff, cdk deployだけでコードにかいたcontext のセットが優先される context では そこまでみない
  • cdk doctor 便利そう 2022/10/15 22:53

    • バグレポート用のものかも
  • --profile を説明したクラメソさんを読むぞ

  • [AWS CDK(Cloud Development Kit)] 複数アカウント・複数リージョンへのデプロイを管理する | DevelopersIO を読んで、 --profile のことを知るぞ
  • まぁ、 --profile については、いい感じに接続するプロファイルを用意して使う という意味だろうけどね
  • $ cdk deploy Stack-prd-tokyo --profile prd

  • こういう書き方のところもあるのね (prd/prod)
  • こうして、 --profile ことも理解した僕は、 業務のCDK(vpcの) readme を完全に理解したのだった
    • ので、実際に自分のawsアカウントで実行していこう
    • 実行して、一箇所変えられるようになったらマスター、おわり

本当に自分のAWSアカウントで実行してみるぞ

結局、自分のawsアカウントで実行するには何が要るのか

このクラメソの実践記事をやってみる 2022/10/16 16:21

  • まず皆さん、AWS アカウントの環境を整えてください。 次に IDE, AWS CLI, Node.js を用意

  • 言われてみれば、自分の awsアカウントわからないかも
  • $ aws-cli がないのでいれる
  • node は入ってた
  • なぜか cdk も元からはいってた
  • $ cdk --version
  • ~/devio$ cdk init app --language python
    • 実践記事で devio/ というディレクトリでやってみよう、となってる
  • 実践!AWS CDK #1 導入 | DevelopersIO をやっていってる
  • クラス名にCfnがついてるのがL1だっけ?
    • そうです(低レベル)
  • ~/devio$ cdk synth
  • devio/app.py", line 4, in import aws_cdk as cdk ModuleNotFoundError: No module named 'aws_cdk'
  • python -m pip install -r requirements.txt
    • 60MBとかある 
  •   #vpc=ec2.CfnVPC(self)
    vpc=ec2.Vpc(self, 'Vpc')
    
    • なんで L1の方は VPCが全部大文字何だろう…
  • ~/devio$ cdk bootstrap
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
[??????????・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・] (2/12)

7:48:17 AM | CREATE_IN_PROGRESS   | AWS::CloudFormation::Stack | CDKToolkit
7:48:23 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role        | ImagePublishingRole
7:48:23 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role        | FilePublishingRole
7:48:24 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role        | LookupRole
7:48:24 AM | CREATE_IN_PROGRESS   | AWS::IAM::Role        | CloudFormationExecutionRole
7:48:24 AM | CREATE_IN_PROGRESS   | AWS::S3::Bucket       | StagingBucket
  • ~/devio$ cat ~/.aws/credentials で、 aws_access_key_id や aws_secret_access_key がつなげる先に S3バケットや CloudFormation Stack が作られるので、接続先が間違ってないか気をつけよう!
  • 間違って作ったときは cdk destroy して、 s3バケットとかをc消せばいいらしい
    • でも、結局は消えなくて、management console からけした気がする
:~/devio$ cdk destroy
Are you sure you want to delete: DevioStack (y/n)? y
DevioStack: destroying...

 ?  DevioStack: destroyed
  • 権限が足りないらしい
~/devio$  cdk bootstrap
 ?  Bootstrapping environment aws
/ap-northeast-1 failed bootstrapping: AccessDenied: User: arn:aws:iam:
:user/superuser is not authorized to perform: cloudformation:DescribeStacks on resource: arn:aws:cloudformation:ap-northeast-1:
stack/CDKToolkit/* because no identity-based policy allows the cloudformation:DescribeStacks action
    at Request.extractError (/home/linuxbrew/.linuxbrew/lib/node_modules/aws-sdk/lib/protocol/query.js:50:29)
  • iam user 全権限 AdministratorAccess
  • CloudFormation::Stack 多分なまえが  CDKToolKit や IAM Policy, Role や S3何かを保存する の三種類を作ってるみたいだね cdk bootstrap すると (全部で12個)
~/devio$  cdk bootstrap
 ?  Bootstrapping environment aws://
/ap-northeast-1...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
 ?  Environment aws://
/ap-northeast-1 bootstrapped.
  • cdk destroyしたときに s3は消えなかったけど、 policy role はきえてそう???
    • 消えてない気が まぁあってもいいか
  • cloud formation の stack ものこってるので消す
    • というか、このcfn が他の全てを作ってるのか 2022/10/22 3:45
  • cfn のstack の削除の様子ってログでないのかな(ぱっと見つからない)
    • 消えたっぽいのでよし 2022/10/22 3:47

改めて cdk synth からやってく

  • synthesize に 20秒くらいかかる
  • もろもろ(vpc subnet routetable igw eip natgw) 作るのに … 結構かかりそうだなあ
    • 20/25 までi wLj i1分20秒くらい
    • 20/25 でなかなかとまってる 1分くらい
    • なにが思いのかは見れなかった
    • =jJ )eつくるのに 3分くらい
  • 確かに vpc や eip ができてた
  • cdk destroy 8:30 開始 2022/10/22 23:13
  • 2分15秒くらいかかった
  • nat gateway とか deletedになってた
    • cdk destroy で消えるリソースもあるらしい
    • 1時間で消えるらしい (deleted になった nat gateway)
  • 引き続き 実践!AWS CDK #1 導入 | DevelopersIO を参考に、業務のcdkを実行していっている.(vpc)
  • cdk list 10秒くらいかかる

業務のCDKのコードを clone してやってくぞ

  • $ git clone @
organization has enabled or enforced SAML SSO. To access
this repository, you must use the HTTPS remote with a personal access token
or SSH with an SSH key and passphrase
that has been authorized for this organization. Visit
https://docs.github.com/articles/authenticating-to-a-github-organization-with-saml-single-sign-on/ for more information.

fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
  • https://github.com/settings/keys で Configure SSO で Authorize すればいいんだっけ?
    • まさにそうだった
  • git clone 成功
  • cdk.json がある階層が実行する階層のようだ (実行時にカレントディレクトリにするディレクトリ)
  • cdk synth -> cdk bootstrap -> cdk deploy の順
  • なんか ipam-pool がないということで失敗した
  • Synthesis time: 14.26s
$ cdk deploy

VPCStack: creating CloudFormation changeset...
[・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・] (0/3)

11:35:28 PM | CREATE_FAILED        | AWS::EC2::VPC     

Resource handler returned message: "The ipam-pool ID 'ipam-pool-
 does not exist (Service: Ec2, Status
Code: 400, Request ID:
 Hand
lerErrorCode: GeneralServiceException)
11:35:29 PM | ROLLBACK_IN_PROGRESS | AWS::CloudFormation::Stack | VPCStack
The following resource(s) failed to create: 
  • 多分、IPAMPool について知っていくのが次のステップになるだろう 2022/10/23 23:38

IPAMPool を設定するぞ

ipam を自分のAWSアカウントに作って、cdk deploy 完遂を目指す

  • とりあえず pool 自分のaws アカウントで作ろうか 手作業で
  • 組織の IPAM の委任管理者ではないことを検出しました。IPAM を作成すると、アカウント内のリソースのみが監視されます。IPAM で組織全体のリソースを監視する場合は、委任管理者のアカウントに IPAM を作成する必要があります。委任管理者を設定するには、組織の管理アカウントとしてサインインし、[設定] ページに移動します。 - って出てきて親切なaws

  • つくってみた
  • プロビジョンとかしなくていいのかな?
  • まぁcdkに書いてみよう
  • 前回うまくいかなかったコマンドは $ cdk deploy
  • vpc/cdk.json に書いた (そこの pool id を読む cdkアプリ が業務の cdk にかかれてる)
  • ipam アカンといわれた
    • does not exist といわれた
  • あるとおもうんだけどなあ
  • スコープタイププライベートがダメなのかな
  • ipam id と pool id は違うのね
  • ipamしかつくってなかった(多分)
  • プール使用率 このプールにはプロビジョンされた CIDR がありません。

IPAM の Locale とは

  • Localが必要と言われた 2022/10/29 0:18
    • ipamのlocal を調べないと池なさそうだなあ
  • [やること]
    • 一般的な ipam local しらべる locale か
    • 業務でどうなってるか見る
  • チュートリアル: AWS CLI を使用して IPAM とプールを作成する - Amazon Virtual Private Cloud
    • チュートリアルを読む
    • お金がかかったりしないのかな? 2022/10/29 0:40
    • ロケールって ap-northeast-1 のこと? ←そうだった
    • 確かにわいのは locale none になってた2022/10/29 0:44
    • 最上位は none になって、リージョンプールをその下に作るっぽい
    • 10から発行されてるぽい 業務のは
  • 業務のは共有プールだから、いきなりリージョンプールだけがあるのね 2022/10/29 0:47
  • じゃあ、自分のでは、トップレベルプールの下に 10. とかのをつくってみようね
  • でかすぎるから /24 とかでいいかも
  • 割り振りはやはり /24 が基本でやってるぽい
  • /17 から /24 が32コとれるのかな いや 128 か
  • 2 4 8 16 32 64 128
    • やはり 2の7上増えてるね
  • 自分ので 10.32.1.0/24 みたいなのをpoolきる
    • トップレベルの下にリージョナルで
  • cdk deploy うったが synth に 34秒かかった
    • 海鮮思いから?
  • 最初にcdk deploy コマンド打ってから通るまで何分かかったか書くといいかもね
  • The allocation size is too big for the pool といわれた
    • allocation size がどこかにあるのね よもう
  • ipv4_netmask_length=24, という記載が業務のCDKにあった
    • ので、 /23でpool を切ろうと思った
  • CIDR をプールに手動で割り当てて IP アドレス空間を予約する - Amazon Virtual Private Cloud
    • 10.0.0.0/24 とか /24 で指定するらしい とおった
  • https://ap-northeast-1.console.aws.amazon.com/ipam/home?region=ap-northeast-1#PoolDetails:PoolId=
    • 保留中のプロビジョンというのは、どこにも割り当てられてない、ってことかな?
  • 失敗したプロビジョン (The CIDR does not exist in the parent pool.) になってた
  • 親で 10.0.0.0/21 する コは /22 でプロビジョニングしたら、ついに cdk deploy が通った
/vpc$ cdk deploy

?  Synthesis time: 14.48s

VPCStack: deploying...
[0%] start: Publishing
[100%] success: Published 

VPCStack: creating CloudFormation changeset...

 ?  VPCStack

?  Deployment time: 42.31s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:

?  Total time: 56.79s

一部修正して反映してみよう (CDK)

vpc$ cdk diff
Stack VPCStack
There were no differences
  • むふう
  • 何かを変えたら↓になった
vpc$ cdk diff
Stack VPCStack
Resources
[~] AWS::EC2::VPC (Stack名) replace
 └─ [~] Ipv4IpamPoolId (requires replacement)
     ├─ [-] ipam-pool-111111
     └─ [+] ipam-pool-222222
  • いい感じ 日字2022/11/01 22:57
  • vpc$ cdk synth
  • いざデプロイ
vpc$ cdk deploy VPCStack

?  Synthesis time: 13.7s

VPCStack: deploying...
[0%] start: Publishing 
[100%] success: Published 
VPCStack: creating CloudFormation changeset...

 ?  VPCStack

?  Deployment time: 54.22s

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:

?  Total time: 67.92s

結局、どのくらい時間がかかったのか

  • (元々、CloudFormation は一通りできる状態だった)
  • 時間の計測結果
    • CDKの勉強+業務のCDKコード読むのに (大部分はCDK自体の勉強) 317分 (5時間強)
    • CDKを自分のAWSアカウントで実行&修正実行してみるのに: 228分 (4時間弱)
    • このブログを書くのに: 162分 (2時間半強) (19300字) (URLやスペースも数えると25000字)
      • 1分120字、1時間7250字
  • 足し合わせると、CDKの修正実行ができるようになるまでに 9時間かかり、 ブログまで入れて全部でも 11時間半強 (707分)
    • つまり、丸々一日使えれば半日(一日)で終わる時間なので、普通だった
      • (半日でこれくらいできるようになるのが普通な感覚)
    • 1日20分なら 35日なので、やはり普通
      • 1日20分なら、1ヶ月でこれくらい1技術習得するのが普通

感想

  • コツコツやって、CDKを修正&反映できるようになって良かった

HTMLフォーマッターgemを作った (hitomalu_formatter)

経緯

  • HTML文字列をフォーマットしてくれる、最近もメンテナンスされてるgemがなかったため作った
  • 特に下記の点を重視した
    • 何回もかけても同じ結果になること (span や p や インデントが増えないこと)

できたもの

似たライブラリ

このようなフォーマットができます

主なルール

  • タグの中身の整形について
    • 開始タグから 非空白文字が始まるまでの 空白文字は削除
    • 行中(= 行の中で非空白文字で囲まれたところ)にある半角スペースは保持 (ただし、2つ以上連続していたら1つにする)
    • 改行や行頭 or 行末の空白文字は、改行前後の行に非空白文字があるなら、半角スペース1つに置換 (非空白文字がない行は削除)
    • 最後の非空白文字から閉じタグまでの空白文字は削除
  • pre 要素の中は整形しない
  • インライン要素の後は 「改行(スペース混じりでも)があれば改行1個にする」「改行がなく、スペースがあればスペース1個にする」(何もなければそのまま)
  • インデントはしない
  • (これ以外にもルールはあります)

例1

<div>      
<p id="kore_id" 
hgeg2>
nakami
  </p><span>2つ目</span></div><a     href="hoge">fuga</a>
  
  
  <pre>        (スペース4つ)
         (a c)
           ||
           人 ←全角スペース
             
           
</pre>

  <!-- コメントしてみた -->
<saigo>aaaa</saigo>

<div>
<p id=\"kore_id\" hgeg2>nakami</p>
<span>2つ目</span>
</div>
<a href=\"hoge\">fuga</a>
<pre>        (スペース4つ)
         (a c)
           ||
           人 ←全角スペース
           
           
</pre>
<!-- コメントしてみた -->
<saigo>aaaa</saigo>

使い方

gem install hitomalu_formatter
require "hitomalu_formatter"
Hitomalu::Formatter.format('<DIV        id=aaa>content</div>')
=> "<div id=\"aaa\">content</div>"

ポイント

  • Nokogiri利用
    • なので Nokogiri に似た感じのgem名にしました
  • テストケースが44種類あって安心
    • すっかりテストありきの人間になりました
  • 100万文字で20000ノード程度のHTMLの場合、2分前後、メモリ5GB程度使います。

詳細 (ここから技術勉強ブログ的内容)

やったこと

フォーマッターを作るにあたって

  • MacLinuxの改行コード(\n) と Windowsの改行コード (\r\n) をあわせるのが大事
  • シェルで使えるコマンドは速い
    • sed の例
      • 100万文字から 20000箇所置換するのが 20ミリ秒くらい
  • paiza の ブラウザで Ruby を実行できるものは便利

高速化で参考にした記事

Nokogiri の挙動などフォーマッターつくりについて

gem にするにあたって

感想など

  • gemは公開すると、それだけでかなりDLされる (数時間で100など)

業務のJSを1テストケースだけJestにしてみた

経緯

  • 業務のJS(結構モダン)をTypeScript にしたい
  • テストが全くないので、テストをまず作りたい
  • テストフレームワークは流行ってるみたいなのでJestにしよう
  • 前回(38日前)、Jest自体は TypeScript の単体テストで Jest 使おう - Qiita をやってみて、一応使えるようになった
  • 今回は、実際の業務のコードを1つJest にしてみる

概要

  • めちゃくちゃ詰まったポイントがあった
    • 業務のコードの拡張子が .js だと、 「ES mocules の import を使いなさい」みたいなError がでたが、 .ts にしたら解消した
    • Jest でテストコード(window.alertが文言指定で出るか) 自体は一瞬で書けた

かかった時間

  • 5/22, 24 作戦考える (5日間開く)
  • 5/28 Jest やりはじめる (~5/30)
  • 6/1 import export のエラーに苦しみ始める
  • (6/18 まで評価資料5月分の方をする)
  • 6/19~6/25 そのエラーに取り組む (1日10~30分)
  • 6/26 ~6/29 そのエラーを突破できたので、先を進める
  • 6/30 ブログを書き始める
  • つまり、2週間弱かな?
  • このブログを書くのに 2022/07/05 1:43 まで 6日間、80分かかった

やったこと

最終的にいい感じに通った時のコード

  • Marumaru という機能があると思ってください
  • npm t するとテストが通る (上のqiita 通りに組んだので)
marumaru.test.ts

import zembu from "../src/marumaru";

beforeAll(() => {
  // window.alertをモックにする。Jestではモックにしないとエラーになる
  window.alert = jest.fn()
});

test('test', () => {
    zembu.add_marumaru('hikisuu1', 'hikisuu2', 'hikisuu3');
    expect(window.alert).toHaveBeenCalledWith('ログインしてね');
});

marumaru.ts

import $ from "jquery";
import "jquery.cookie";

const add_marumaru = function (hikisuu1, hikisuu2, hikisuu3) {
  略
    alert('ログインしてね');
};

略

export default {
  add_marumaru,
  add_kakukaku
};
  • …と、何の変哲もない(?) ES Modulesなコードだった
    • しかし、 marumaru.ts ではなく marumaru.js にしてたため、長いこと import 周りで悩んだ

詰まる前編

export のエラー文言が出る試行錯誤編

cross-env編

にっちも察知もいかないから0からやる編

  • ↑↑↑のQiita 自体で練習はできたので、それから、少しずつ、やりたいコードに変えていけば、おかしくなったところがどこか気づける作戦
  • tsconfig.json の "module": "commonjs", がだめそう 2022/06/21 22:54
    • 最終的には此れで問題無かった 2022/07/04 2:43
  • package.json の "type": "module", も 最終的には此れで問題なかった
// 近しいpackage.jsonのtypeがmoduleなので、このファイルはESMで読み込まれる
import './sample/setup/init.js'; 

// ./node_modules/foo/package.jsonにはtypeが書いてないため、CJSで読み込まれる
import 'foo';

とのことなので、 type: module だと、 eS modules になるのだろう  ぜ ぜ - まぁ、おいおいわかっていくだろう

まだまだ試行錯誤編

  • なんか、いけそうな気もしてるたので、なかなか0からというか、上手くいったやつから寄せていかなくて苦労してる
  • module.exports を export default { にもどしたら、おなじみの SyntaxError: Unexpected token 'export' がでた。
    • 一度諦めてcommonJS形式にしたときの記録
      • JSは同じことについて運種類も書き方があって難しい ユーザが必要な機能を次から次に実装していいた結果
        • とはいえ、ややこしいだけで普通に習得していけるものなのだろうと思う 難しくて時間がかかるけど
  • やっぱり最初からやろうか。
  • 最初から練習でうまくできたqiita をやったら そのまま npx tsc -init したら、かってに module:commonjs になった
    • 最終的にもこれでうごいてた
  • npx tsc -init
Created a new tsconfig.json with:                                                                                       
                                                                                                                    TS      
  target: es2016
  module: commonjs
  strict: true
  esModuleInterop: true
  skipLibCheck: true
  forceConsistentCasingInFileNames: true
  • "module": "es6", / Specify what module code is generated. / にしてみた 2022/06/22 22:52 11m だめだった 2022/06/22 22:52 ES2022でもだめ e 
    • タいしゅうてきには "module": "commonjs",

モジュールの CommonJS形式と ES Modules 形式

再び、上手くいった練習と見比べ

  • ちゃんとテストがうごいてる jest_rensyuu と見比べたり、jest_rensyuu に合わせていって、設定には問題なく、コードに問題があることを発見した
  • export - JavaScript | MDN
    • 書き方が大量にありすぎて難しすぎる js 2022/06/24 1:31
  • jest_rensyuu では ES modules で上手くいってるのでこのままでいけそうな気もしなくもない。
  • export default と export const で違いがあるらしい (default export, named export)
  • 中途半端には jest は es modules export, import に対応してそう 2022/06/25 0:35
  • 役立った素晴らしい記事

少し前進

  • export const add_marumaru = function (hikisuu1, hikisuu2, hikisuu3) { みたいな形式から export function add_marumaru (hikisuu1, hikisuu2, hikisuu3) { にしたら進みだした

やっと解決編

  • ファイルの名前を marumaru.js から marumaru.ts にしたらじごくくの Must use import to load ES Module: C:\Users\tetsuo_yamada\marumaru_jest\src\marumaru.js がたなくなった
  • ts-loader みたいなのが挟まってるから?(?)
    • やってればおいおい分かるだろう(?)

普通にjestを書いていく編

  • referenceerror document is not defined jest
  • よくあるエラーぽい
  • jest の環境ではそのままだと docuent がないよと。 2022/06/26 21:13
  • ぴったりそうな記事
  • 数あるJavaScriptテストツールの中からjestを選んだのは、jest-puppeteer、jest-image-snapshotなどpuppeteer関連で使い勝手が良さそうだったからです。

  • puppeteer がいるのかな ?
    • 要らなさそうだった 2022/07/05 1:41
  • 作成時にテスト環境としてnode.jsかjsdomを選択していると思います。node.j指定だとこれからのテストでdocument is not definedとエラーになるためjsdomを指定します。

  • // testEnvironment: "node",
  • testEnvironment: "jsdom",
  • なるほど。頼れる 
  • npm install jest-environment-jsdom がいりそう

alert をテストする編 2022/07/05 1:42

感想

  • JSは書き方がたくさんあってタイへん

この次

  • 多分、運用できる状態を整えて、1関数分テストを完備して、導入する
    • TSまで行けるか?
    • 似た部分が多い関数なのでなんとか集約できるかも

Jest(JavaScriptテストライブラリー)をやってみた

前回: TypeScriptの組み込み方を学んだ(webpackで ts-loader), webpack plugin 色々 - t_hazawaの日記

経緯

  • あるプロジェクトのJSをTypeScriptにしたい
  • 前回までで、TypeSctipt自体は結構学んだ
  • テストがまだ
  • Jestやってみた

やったこと

  • TypeScript の単体テストで Jest 使おう - Qiita
  • jest も npm で入れるものなのね
  • この Qiitaのことを自分でもやってみた
  • Windows10 VSCode でやってる
  • npm init -y
    npx tsc -init            
    npm install typescript    せよと言われたのでした
    npx tsc -init 
    
  • npm install ts-node したら npm t (テスト実行コマンド)通った
  • テストもテスト対象も src/ に入れたらできた
  • やりきった

  • 実際に、プロダクトのJSをTSにすべく、計画を立てる (どこをやってみるつもりとか)

TypeScriptの組み込み方を学んだ(webpackで ts-loader), webpack plugin 色々

前回: サバイバルTypeScriptを読んだ - t_hazawaの日記

やりたいこと・概要

  • TypeScriptになってないが、そこそこJSがモダンなプロダクトがある
  • TypeScript を導入したい
  • 前回、TypeScript 自体を勉強した
  • TypeScript をどう導入するかしらべたぞ
    • 大体 webpack で ts-loader

時間まとめ

今回

  • 2/28-3/7 に組み込み方まなんでいた
  • (3/9-3/31 まで評価資料作ってた)
    • 今度から、月の最後の2日間を毎月当てようと思う(各月2時間弱)
  • 4/1-4/23に続きを学んだ
  • 4/24-4/27 にこのブログを書いていたが、その後、4月分の評価資料を作り始めたら、ストップウォッチを使わず、1日にちょこっとずつしか進めなかったので、12日間も評価資料(4月分)を作っていた
    • モチベが低い作業はストップウォッチを使わないと本当にほんの少ししかしない(学び)

つまり

  • TSの組み込み方の勉強には1ヶ月かかった

勉強したこと (まとめ)

  • webpack.js の module: { rules: [ で test で .ts だけを ts-loader に流し込むことができるのだ
    • 流し込んだやつを他のJSと一緒にバンドればいいのだ
  • 我々の プロダクトは yarn で package.json のことを実行し、そこに "scripts": { "build:prod": "webpack --config webpack.prod.js とかかれてて、webpack を実行してる
  • package.json のことも調べた

勉強したこと (詳細)

Jest 編

まだ謎なこと

  • Jestの運用への組み込み方

次回

  • Jest を今のプロダクトのどこに組み込めるか考える
    • Jenkins?
  • どのように導入しようと考えてるか共有する
  • 一箇所で導入してみる

サバイバルTypeScriptを読んだ

経緯

読み終わった感想

読んで学ぶ部分がボリューミーでした (そこだけで18時間)
(今日ブログ(5万字メモがある)にします)『サバイバルTypeScript』はJS自体とTS自体を全体的に網羅していてよかったです。
JSの説明については、ところどころ簡潔すぎて、「これだけの説明ではわからなさそう」という感じのところがあったので、そこだけ『JavaScript初心者から中級者になろう』で詳しく知るといいかも、…と思いました。『JavaScript初心者から中級者になろう』は懇切丁寧で著者のuhyoさんの話も面白いのですが、何分量が多いですね。

かかった時間

  • 2022/1/29 - 2/22

はじめにから

https://typescriptbook.jp/

3000時

最短を目指してるらしい

> rubypythonなどの動的型付け言語を主に扱ってきており、型をそこまで意識してこなかったので、型システムについて学ぶ必要性を感じている。 

あらまし

400時

特徴

1800時

> TypeScriptはMicrosoftにより2012年10月1日に発表されました。

コンパイルがいります

> 何よりたのしい

たのしみ

型推論のおかげでタイプ量がだいぶ減るらしい

> これまでjavascriptに型がないことにより悩まされてきた"実行してみないとわからない"恐怖から解消され、プログラミングを楽しくできます


JavaScriptはTypeScriptの一部
500時

誕生の背景

> 代わりに、大規模開発の一部はtypescriptが引き受けることになったのです


今日は補助的な道具の上まで

2022/01/29 14:20 今日はおわり
  13:15に始めたので確かに一時間くらい
、

続き 2022/01/30 11:30

6300じ


> 1997年に、Microsoftが企業向けウェブメーラーとして、Outlook Web Access 2000を市場投入しましたが、これはJavaScript製のウェブアプリケーションでした。現代の我々からすると意外かもしれませんが、この時代のJavaScriptはまだサーバーと通信することができませんでした。そこで、Microsoftはこのアプリのために、後のXMLHttpRequest(XHR)となるXMLHTTPという機能をInternet Explorerに追加したりもしました

> google mapの成功を目にした開発者は、ブラウザさえあれば他に何もインストールする必要がないアプリケーションをユーザーに提供できるウェブアプリケーションにより一層の魅力を感じるようになり

むしろ、なぜネイティブアプリはあんなにインストールに時間がかかるのだろう 2022/01/30 11:42

> 2005年には、javascriptアプリケーションフレームワークの先駆けであるprototype.jsがリリースされました。翌年にはjqueryがリリースされ、その後しばらくして、2009年にangularjs、2010年にbackbone.js

> 2009年に発表されたcoffeescriptです。coffeescriptrubyのような簡潔な文法でコーディングできることが魅力の言語で、サーバーサイドフレームワークruby on railsにもフロントエンド開発用言語として正式採用されました。coffeescriptにはclass構文があり、

> 2012年に発表されたのがtypescriptです。

> 当時、人気を博していたcoffeescriptjavascriptの文法とはドラスティックに異なる独自路線を打ち出したのに対し、typescriptはjavascriptの文法を拡張するに留める「javascriptのスーパーセット言語」としての戦略を採用しました


> typescriptが誕生当初に掲げていた3大特徴のうち、モジュール性はjavascriptの仕様にも盛り込まれ、その部分ではtypescriptは優位性を失いました。 

スーパーセット もじゅーる 型

エコシステム

2000時

2022/01/30 12:05

> 静的型検査での同様な立ち位置の技術としてflowが挙げられます

> flowには独自の言語がなく、あくまでjavascriptにコメントのような型アノテーションを追加しただけになっています

> これは不具合が含まれた製品がリリースされることが少なくなるということを意味します。。。これが型指定が多少面倒でもtypescriptやflowを導入する理由の一部となっています。 

> トランスパイラはtypescriptの他に、coffeescriptdartがあります

> トランスパイラの一種にbabelというツールがありま す

モジュールバンドラのwebpack, parcel

> タスクランナーは、ある決められた処理を実行しやすい形にまとめて、実行の順序などを意識せずに実行できるようにするツールです。gulpやgruntなど


> パッケージマネージャー npmや、npmを拡張したyarnが使われています。

> コードフォーマッタ よく使われるのが、Prettier(プリティア)と、ESLint(イーエスリント) Prettierはコード整形を主目的としています。一方ESLintはコードの間違いなども指摘してくれます。
 
2022/01/30 12:33 よみおわ 


なぜ使うべきか

2022/02/01 0:38 https://typescriptbook.jp/overview/why-you-should-use-typescript

4000時 (1200時引くといい全体から)

> airbnbによると、typescriptを使っていたらairbnbの38%ものバグを未然に防げたと見る分析を発表しています。 


> 静的チェックがあるおかげで、typescriptで検出できる類のバグはテスト工程から省略できるのは確かです

> typescriptの場合はひとまずjavascriptとして書き始め、少しずつtypescriptを学んでいき、徐々にtypescriptの恩恵を最大化するようにコードを手直ししていくといったアプローチが可能です

>  typescriptにはjavascriptにはない数多くの機能がありますが、どれも選択的に導入していくことができます。 


過去のesにもトランスパイルできるし、ESNextもどんどん取り入れてるらしいTS

新しいAPIは過去のesバージョンではつかえないとのこと

> もし、古い環境で新しいAPIを使う必要がある場合は、core-jsなどのポリフィルを併用することで解決することができます。 


プログラム言語人気ランキング9位
https://insights.stackoverflow.com/survey/2020#most-popular-technologies

PHPのひとつ下

静的型付け

2400時

> 静的型付け言語は「コンパイル時」に型が定まる。 

静的型付け言語にはコンパイルがあるんだね

> おかしな代入を早期発見できるというのが、typescriptを始めとした静的型付け言語の大きな利点になるわけです

めったに通らないパスでも確実に検出できてすごい 2022/02/01  1:14

> 動的型付け言語では書く必要がなかった型注釈を、typescriptでは基本的には変数ごとに書いていくことになります 

過去には静的→動的→静的という変遷があった

ECMAScript

2022/02/01  1:18

4200時

まぁ今日はここまで読めばいいかな

> netscape社は、javascriptを標準化するために、国際規格策定団体ecmaインターナショナルに依頼します。 javascriptが商標というのも一因だと考えられています javascriptは当時sunが所有する商標でした。その後、権利はoracleに引き継がれます。


> ecmascriptの規格番号はecma-262です。他にもjson(ecma-404)やc#(ecma-334)などがあります

stage3 になったあとにやっぱやめた、にはならないのかな?

> ecmascriptが決めるクライアントサイドjavascriptの仕様は部分的です

> JavaScriptのうちブラウザ仕様に関する部分は、HTML Living Standardが決めています。ブラウザでJavaScriptを使うと、触れることになるのがwindowオブジェクトやHTMLDivElement、ローカルストレージなどのAPIです。これらはHTML Living Standardと呼ばれる規格が定めています。この規格はEcmaインターナショナルとは異なる標準化団体WHATWGが策定しています。

> 「javascript」と一言で言っても、複数の規格で構成されているわけです

> 主要なブラウザの内部を分解すると、レンダリングエンジンやjavascriptエンジンと呼ばれる部品の単位があります

> JavaScriptエンジンには、主要なものでV8、SpiderMonkeyJavaScriptCoreがあります。

> 有名なレンダリングエンジンは、Blink、GeckoWebKitがあります

> Google ChromeはBlinkを、SafariWebKitを組み込んでいます。

> OperaレンダリングエンジンもPrestoでしたが、Blinkに変更した経緯があります。

> 同じブラウザブランドでも、iOS版のブラウザのレンダリングエンジンはWebKitです。たとえば、Google ChromeはBlinkを採用していますが、iOS版のGoogle ChromeレンダリングエンジンはWebKitです。これは、iOSレンダリングエンジンにWebKitだけが独占的に利用を許されているためです。


Firefox-Gecko-SpiderMonkey


いかにもapple製なJavaScriptCore

やはりJSはLinuxほどは面白くないのでは? 2022/02/01  1:44
 やっぱり結局はプレゼンテーションのところだけ感がある

ヨミオワ 2022/02/01  1:48

射程

2022/02/01 22:12

4000時

> typescriptを学んだらどのようなソフトウェアを作れるのか

ついさっき思ったことを説明し始めててすごい

tsはもちろん node.jsでも使えるよ

> バックエンド言語はjavarubyphpなどの多数の競合があるものの、typescriptもサーバーサイドプログラミングのひとつの選択肢になります。

> 両方でtypescriptを採用するメリット

> プロジェクトで扱う言語が1つでよい

バックエンドに向いてるのかな?


> モジュールを共有できる テストが倍にならない

フロントとバックでモジュールはどのくらい共通するのかな

> その言語のエコシステムや実務上のベストプラクティス、言語の細かい癖や陥りがちな罠などまで、しっかり理解した実践レベルに到達しようとなると、多くの学習時間を要します

> デスクトップアプリケーション。。windowsmacoslinux向けにデスクトップアプリケーションを作る場合もtypescriptが使えます。デスクトップアプリケーションをjavascript、html、cssの技術スタックで開発できるelectronを用います。 

> electron+typescript製の著名なアプリとしては、slackやmicrosoft社のvs codeがあります

なるほど

> cliアプリケーション。。コマンドラインツールの開発もtypescriptで行えます。サーバーサイドjavascript実行環境のnode.jsとtypescriptを組み合わせて開発します。

> CLIアプリケーションフレームワークには、Heroku製のoclifなどがあります Google製のzxを用いると、シェルスクリプトの代わりにTypeScriptを使うのもしやすくなります。

なんでもTypeScript

> Next.jsと親和性の高いVercelのServerless Functions、静的サイトホスティングで有名なNetlifyのNetlify Functions、世界90カ国194の都市にエッジを持つCDN CloudflareのCloudflare Workers


> typescriptでもiacを行えます。awsのインフラ構成を自動化するツールにaws cdk(cloud development kit)があります。これはtypescriptをサポートしています

たしかに

> AWSGoogle Platformなど複数のクラウドベンダーに対応したインフラ構成ツールとして、Pulumiもあります

> TerraformはHCLと呼ばれる独自言語で記述するのに対し、PulumiはTypeScriptなので、TypeScriptプログラマーにとって手が届きやすいツールです。


> google spreadsheetなどには、javascriptで機能を拡張する仕組みが備わっています。それをgoogle apps scriptと呼びます

自動化とかできるらしい

> typescriptで書いたコードはjavascriptコンパイルすれば、google apps scriptで利用できます

> ブラウザ拡張はjavascriptで書くことができます。typescriptで書いたコードもjavascriptコンパイルすることで、ブラウザ拡張として動かせます

いろんなところに使える JavaScript


> TensorFlow.jsはGoogleが開発した機械学習ライブラリです。Brain.jsはニューラルネットワークのライブラリです。 

> WebAssembly(WSM)はブラウザで動くアセンブリー言語です。WSMはJavaScriptよりも高速な処理が必要とされるところで用いられます。WSMのプログラムはC言語C++、Rustといったシステム言語で開発されることが多いですが、TypeScriptでWSMを開発できるようにする試みも出てきています。その筆頭がAssemblyScriptです。


2022/02/01 23:09


> Javaのキャストみたいなのはないよasは違うよ。instanceof Interfaceはできないよ。

作って学ぶ編

一通り React, Next.js, Jest(テスト) Prettier(整形), eslint(リンター)できるといいかも

eslintって小文字なんだ全部

開発環境

2000文字
一旦、今日は読むだけ読んで、明日やってみよう


> ブラウザはJavaScriptからHTMLを操作する必要があるのでDOM APIがありますが、Node.jsにはありません。代わりにNode.jsには、サーバーサイドのさまざまなリソースを制御する必要があるので、ファイルシステムにアクセスするAPIやHTTPサーバーを建てるためのAPI、プロセスを起動したり終了したりするAPIなどがあります。

なるほど。結構別物なのでは?


> Node.jsは、JavaScriptをサーバーサイドで動かすことを目的に開発されたソフトウェア

なんでもJavaScript の一環なのだ


Linux にも brew があるらしい

簡単な関数を作ろう編

2000時 今日はここまで読もう
 明日やってみよう


> コンパイラが指摘する問題点をすべて解消する作業のことを「コンパイルを通す」といいます。

懐かしい作業なのだ VC++

よみおわ 2022/02/02  0:27


●では実践しよう 2022/02/02 22:04

まずbrewを入れましょう

https://tech-blog.cloud-config.jp/2019-07-19-homebrew-on-wsl/

Homebrew
ホームディレクトリにパッケージをインストールできる(sudo不要)

> 使用しているディストリビューションでパッケージ化されていないソフトウェアもインストール可能


sudo apt update&&sudo apt upgrade

したが、いま 45分経過して snapd 212 

43分で 213くらいのパッケージをDLしたようだ

2022/02/02 23:03 58 分 apt upgrade がおわった


2/03 23:10くらい
もういっかい sudo apt update && sudo apt upgrade してみよう

チェックに割と時間がかかるね

いや、 12個本当に更新があったようだな…
1分くらいでおわった

slはいった 2022/02/03 23:46


●サバイバルTypeScriptにもどる 2022/02/03 23:48

https://typescriptbook.jp/tutorials/setup

brew install node@16

に10分はかかってる 2022/02/03 23:57
12分くらいでおわった

なんか入らなかったみたいなので
sudo apt install nodejs

してる

satoshi_takami@sa-takami-dl:~$ node -v
v10.19.0

めちゃふるかった

再度
brew install node@16

2022/02/04  0:04

echo 'export PATH="/home/linuxbrew/.linuxbrew/opt/node@16/bin:$PATH"' >> ~/.profile

して wsl立ち上げ直したら 16.13.2になった

tsc -v できた
2022/02/04  0:07

多分環境つくりできた 2022/02/04  0:07

2022/02/05 0:10 今日の実践開始

Reactでいいねボタンを作ろう

突然React

2022/02/05  0:19

まず読むか

> reactはfacebook社が開発したuiを作るためのパッケージ

Meta

> uiが複雑になるとreactなしではコードの記述量が増大したり、可読性が悪くなったりと難易度が上がります

> なんといっても、uiが今どのような状態なのかを管理するのは、プログラマが把握しきれない複雑さになることがあります

Reactはパッケージ

React の必要性わかった


> Reactでは 見てのとおり、どのように表示するかの部分はなく、「このような表示になってほしい」という目標だけが書かれています。

宣言的なコードつよい(命令は大変)

> ページもコンポーネント

> コンポーネントベースのメリットは、同じコンポーネントを再利用できる点です オープンソースコンポーネントも数多く公開されています

yarn 一瞬ではいった
2022/02/05  0:40


npxコマンド…? 2022/02/05  0:40

https://zenn.dev/ryuu/articles/what-npxcommand


> npxコマンドを使うことでインストールされていないコマンドであっても自動的に探してインストール、実行まで行ってくれます。

実行したあとはパッケージの除去まで行ってくれるため、環境が汚れる心配はないそうです。 インストールするまでも無いけど手軽に試したい、環境を汚したくないそんなニーズに

なるほど


npx create-react-app like-button --template typescript

3分くらいかかったけど


yarn start

react が ローカルサーバを用意してるのかな


> このHTMLに見える部分はJSXと言われるものです。JSXはJavaScriptを拡張した言語で、JavaScriptの中にXMLを直接書けるようにしたものです。

> jsxを戻り値にする関数をreact用語で「関数コンポーネント」と言います。 画面の部品をコンポーネントにしておくと、再利用できたり変更が一箇所で済んだりと、開発や保守がしやすくなります。


 今回作るボタンは次の図のようなシンプルなものです。 まで
2022/02/05  1:08


2022/02/07  0:43
機能はお腹がいたかったので休み

なんと.tsxの最後にcssをかける
駆けなかった App.cssだった

    cursor: pointer;

で手のマークになる

よく見る useState 関数

> setCountにはcountの値を変更する関数が代入されます。

> 次に、span要素をクリックしたときに、countの値を増加するhandleClick関数を実装します。

むずかしい

こーどよんだらよくわかった

まぁわかったかも 2022/02/07  1:00

17分しかやってないのでもう少ししよう

Next.js を調べるだけしようかな


https://qiita.com/Yuki_Oshima/items/5c0dfd8f7af8fb76af8f

語気がつよい 2022/02/07  1:02

けどしっかり書かれてそう


> Next.jsはモダンかつ強力なフロントエンドフレームワーク

React との関係はなんなのかな?

Reactの上にさらに載ってる感じみたいだね

> Next.jsはサーバーサイドレンダリング(SSR)やファイルベースルーティングなど多くの機能をゼロコンフィグで提供してくれます

> 開発会社Vercelが同名のプラットフォームVercelを展開しており、デプロイ/ビルド/配信までを一気通貫に提供

> Reactをベースにしている以上、Next.jsを使うべきかの判断はReactとの比較がポイント

Reactを強化したようなものなのかな? 2022/02/07  1:06

こういう5つの観点というか考慮ポイントがあるのね
 何を採用するか

> next.jsはアプリケーションを事前にページ単位でレンダリングします。クライアントからのリクエスト時にレンダリングするのがssr(server side rendering)と呼ばれる機能です。またビルド時にレンダリングする機能もあり、ssg(static site generation)と呼ばれます。 

サーバで処理するのね Next.js は、で、Reactに近いと
 Reactは クライアントでうごく

> またurlごとに個別のhtmlが生成されるのでseoに有利です。

HTMLがあると安心(?)

> 実用上リクエスト時までページの(静的な)内容が確定しないことはまれです

ログイン部分はJSでつくろうね

30分したのでおわり 2022/02/07  1:13

さて、具体的にssr/ssgを同実装するのかを から

> getStaticProps(SSG) を exportするだけ

> getServerSideProps(SSR)


getStaticProps() を実装して export async する

props: {
}
の中にあるのを function Blog  が処理するっぽい


☆ Next.js の方が SSG だからナウいし、早くてSEO的によさそう!
 つい今日、AmazonSSRして撃はやって記事をみたし
 SPAは表示までおそそう
    (謎のスプラッシュ挟むサイト多いし)

Next.js はルーティングがファイルのあり方に対応してて楽ちんらしい

> _app.tsxや_document.tsxは特殊なファイルで、URLには紐づけられません。これらはアプリケーションのエントリーポイントとしてReactのContext Providerを記述したり、HTMLのヘッダーを記述するために使います。

なるほど

> pages/post/[pid]/[comment].jsに対して/post/abc/a-commentというURLでアクセスすると

{ "pid": "abc", "comment": "a-comment" }

> next.jsの開発サーバはソースコードの変更を検知して、stateを保持したまま変更があった個所だけを更新してくれます。これにより、開発体験が大幅に向上します。例えば、フォームに入力した内容を保持したままタイトルのfont-sizeを変更することなどができます

うむう

> Next.jsでコンポーネントを書く際は常に関数コンポーネントに名前を付けてデフォルトエクスポートするようにしましょう。

> Next.js 10.0.0から専用の画像コンポーネントが追加され、配置されるサイズに応じて元画像をトリミングして配信してくれるようになりました。必要なサイズのデータだけをダウンロードするので画像の表示を大幅に高速化できます 

> レスポンス表示で幅が小さくなった場合も自動でそのサイズにトリミングした画像を生成してくれます。

すごそう


> 手書きでwebpackの設定を追加していくとしてもwebpackの設定ファイルを直接書き換えるよりはるかに楽です  Reactで細かいwebpackの設定をする際にnpm ejectしてwebpack.config.jsを編集することになりますが、かなり難しい作業です。


> 動的インポートしたコンポーネントはクライアントサイドでレンダリングされるため、実質的にReactと同じように処理される


ページ全体を SSGで作るには Next.js はいいんだろうけど、部分的な置き換えには使えなさそうな気がしてきた
 (React はどうだろう??)


>     Next.jsサーバへリバースプロキシ(next start)
    完全な静的リソースを生成してwebサーバから配信(next export)


> SSRを全く使わないならnext exportコマンドでReactと同じように静的リソースを生成することもできます。あとはそれをwebサーバに返してもらうだけです 

2020年12月のQiita

ヨミオワ 2022/02/07 18:45

きりいいのでおわろうかな

ーーー 2022/02/08 19:09 サバイバルTypeScriptに戻る

https://typescriptbook.jp/tutorials/jest Jest…は会社のプロダクトでやってる気がするからいいかな

Prettier 編 2022/02/08 19:10

https://typescriptbook.jp/tutorials/prettier

これはやりたいなぁ VSCodehttps://www.digitalocean.com/community/tutorials/how-to-format-code-with-prettier-in-visual-studio-code-ja

ググって一番上にでてきた


4ふんやった あと26ふん



VSCodeのPrettier は 1850万インストール


普通にフォーマットできた 2022/02/08 21:11


jsにもcssにもつかえるよ


.prettierrc.yml とかをつくろうね

やりきった 2022/02/08 21:16

次が何かみるだけしようかな

●eslintへん2022/02/08 21:17

https://www.google.com/maps/@34.6827335,135.188615,926m/data=!3m1!1e3?hl=ja
eslint prettier 違い 2022/02/08 21:17

https://qiita.com/soarflat/items/06377f3b96964964a65d
これを読もうかな 2022/02/08 21:18

まぁ、おわり

2022/02/09 22:06 よみはじめ

> eslint --fixでコード整形ができる
がraibaる


> 何故eslintだけではなくprettierも利用するのか

> eslint自体の説明は記載しておりません

むふう

> 読み方はプリティア

基本、フロントエンドだけに対応なプリティア

> npm install prettier@2.3.0 --save-dev

開発環境で使いたいものだもんね

> ファイルを上書きするために--writeオプションをつける。

prettier app.js --write

> eslintでもeslint --fixでコード整形ができるが、prettierの方がコード整形が優れている

> eslintと比べて手軽で確実に整形できる。。eslintでは整形できないコードを整形できる。。以下のような一行の文字数が長いコードはeslintでエラーが出力されるが、整形はされない。

つよい

> 上記のような整形をしてくれれば、複数のメンバーがエラーに対する独自の修正を適用し、更新するたびに差分が出てしまうような事態を防ぐことができる。


> eslint --fixは設定に該当したエラーのみを整形する。そのため、設定次第ではコードを整形しきれない。Prettier はデフォルトのスタイル(整形ルール)が存在する

ゼロコンフィグ


> 
    eslint(ESLint 本体)
    eslint-config-prettier(ESLint のフォーマット関連のルールを全て無効にする、要は Prettier が整形した箇所に関してエラーを出さなくなる)


http://tempest.blog.jp/archives/50414936.html
rc は run command らしい


package.json は scripts フィールドに、 実行コマンドをカケるんだね

> gitにはコミット前に指定のスクリプトを実行できるpre-commitフックと言う仕組みがある



> npm install husky@6.0.0 lint-staged@11.0.0 --save-dev
> 
    husky(Git のコミット時やプッシュ時に指定したコマンドを実行できる)
    lint-staged(Git のステージングに追加されたファイルにのみに ESLint などのリントを実行できる)


> npm set-script prepare "husky install"

package.json の "scripts" フィールドに "prepare" を追加するコマンド

> prepareはnpm installなどを実行時に自動で実行される。

読み終 21分かかった もうちょっとしよう 2022/02/09 22:28


eslint typescript vscode で検索


一番上の https://qiita.com/yuma-ito-bd/items/cca7490fd7e300bbf169

をやってみよう

2020/8/30

あんまりVSCode のことは載ってないかも?

VSCode の ESLint も 1850万インストール
  Prettier とかなり同じ

自動でならないが?

30分たったので、明日はこれが自動で整形されるようにしよう2022/02/09 22:36

2022/02/12  0:19 機能は会議がおおかったのでスキップなのだった

ESLint と Prettier を同時に format on save したいが動いてないだった

あのqiitaではうまくできないので、他の情報源を使うことにする

vscode eslint 動かない で検索 2022/02/12  0:26

https://note.kiriukun.com/entry/20190817-eslint-not-working-in-vscode
 むずかしい

https://iwb.jp/vscode-editor-eslint-error-reasons/
なるほど

https://qiita.com/genbu-jp/items/a48bcb9df209b71c2de3

eslintは結構めんどくさいようだ
 prettier は簡単 2022/02/12  0:35

> eslintは、javascriptのための静的解析検証ツールでコーディング段階でソースコードの不整合などをチェックすることができるソフトウェアです

まぁ、一箇所に集約した方がかなり楽だからね きっと高度なことをしてるんだろう

難しいせいで小言をいわれた

> eslintは解析検証ツール

> npmは、node package managerのことです

> node.jsのバージョンを容易に切り替えられるnvm-windowsを導入します。

eslintのために npm を入れるために node を入れるために nvm-windows をいれる

四段重ね (Prettier は1段) 集約のためには仕方ないね

> nvmは、node version managerのことです

> eslintプラグインは、eslint本体とvs codeを繋げてタイムリーなコード入力サポートやエラー検出を実現します。


 nvm use 16.14.0
exit status 1: ?A?N?Z?X???????????????B

読めない

管理者権限か? (エスパー)

管理者権限だった

まぁ、 管理者権限で cmd 立ち上げて nvm use したら

vs code terminal でも


nvm list

  * 16.14.0 (Currently using 64-bit executable)

ってなったんでいいんでない


この 5 LGTMのqiitaの おかげで format on save できました

46分2022/02/12  1:03

2022/02/12も腹痛でやすみ

●husky編 2022/02/13 15:02

途中でみたぞ 

やっぱり作りかけなので調べてやるぞ

husky vscode

husky はvscode拡張機能にはなさそう

なんかhusky は windowsだとバグだらけっぽい

https://tamiblog.xyz/2021/02/17/post-1667/


まぁ、このあとに VSCode ESlint でやってみましょう


まぁ、husky のこと調べてそれで一旦はよしとしようか

https://qiita.com/tags/husky

あんまり流行ってない気が LGTM 51とか

https://www.vektor-inc.co.jp/post/use-husky/

これを読んで勉強したことにする2022/02/13 15:22


> husky は npmパッケージ 
> こういった小さな積み重ねが開発スピートに関わってきますので、大事ですね。

一応 vs codeでやってみようか
npmコマンド

まぁ vscodeだとなんか動かなかったみたいだ

まぁ読んだのでおわり 最初はここまでカチカチにしなくてイイダろう

 「読んで学ぶ」編 2022/02/13 15:30

> 本章の流れは、コード上の小さいパーツから大きいパーツに行くように構成しています。 

値など 2022/02/13 19:23

https://typescriptbook.jp/reference/values-types-variables

> letは変数の初期値なしで変数定義できます。初期値なしの変数の値はundefinedになります。

> 基本はconstで変数宣言をして必要な場合にのみ、letを使うのがオススメです

安全なconst


varの問題点
https://typescriptbook.jp/reference/values-types-variables/vars-problems

グローバルで var innerWidth を定義すると window.innerWidthになる

> letやconstはグローバルなスコープで定義されることはない

> JavaScriptで宣言された変数はスコープの先頭で変数が生成されます。これは変数の巻き上げと呼ばれています

Cは戦闘でしか宣言できなかったね
JSはしらんかった

> varでの変数巻き上げでは参照エラーとならないため、意図せずにundefinedの値を参照し予期せぬバグが発生する危険性があります。

letとconstでは、宣言前の変数を参照するとReference Errorが発生します。


  var x = 1;
  {
    console.log(x);
  }
はエラーにならないが

  var x = 1;
  {
    console.log(x);
    let x = 2; 
  }
は巻き上げがあるのでエラー

let, const はブロックスコープだから上書きしにくい


型推論まできた
https://typescriptbook.jp/reference/values-types-variables/type-inference

17min
2022/02/13 19:40

> let x = 1; // let x: number = 1;と同じ意味になる

型推論は静的型付け


> javascriptのプリミティブ型の1つ目の特徴は、値を直接変更できない

そうなんだ

> オブジェクトには、値を後で変更できるというミュータブル特性(mutable)

> 文字列や数値などのプリミティブ型は、プロパティを持ったオブジェクトとして扱えます。。プリミティブ型をまるでオブジェクトのように扱えるのはjavascriptの特徴

> javascriptには、プリミティブ型をオブジェクトに自動変換する機能があります。この機能はオートボクシング(autoboxing)、自動ボックス化


> bigint型: 9007199254740992nのようなnumber型では扱えない大きな整数型。

しらないぷりミティブ型があった

論理型まできたぞ

2022/02/13 19:52 29min

TypeScriptの型推論とかは、この7つの型の識別しかしないのかな?

> TypeScriptには大文字で始まるBoolean型がありますが、これとbooleanは別の型です。

30分立ったのでおわり 2022/02/13 19:53


数値型から再開 2022/02/14 23:00

当然ながら、JavaScriptのことは、ほぼすべてJS中級者でみた

桁区切りのアンスコはどこで区切ってもいい

Number と numberは別よチュュ位シてね

> 整数について言うと、他言語の64ビット整数型の範囲より狭いので注意しましょう。

> 0.1 + 0.2は0.3になってほしいところですが、計算結果は0.30000000000000004になります 0.1 + 0.2 === 0.3; //=> false

> ちなみに、2進数で有限小数になる0.5や0.25などの数値だけを扱う計算は誤差なく計算できます。 0.5 + 0.25 === 0.75; //=> true

> 整数の計算は誤差が生じない

> (110 * 11) / 10 === 121; //=> true

> 小数計算の誤差問題を包括的に解決したい場合は、decimal.jsのような計算誤差がないパッケージを使うのも手です。

> javaなどの言語では、ダブルクォートで文字列リテラル(string型)を表現し、シングルクォートで文字リテラル(char型)を表現するといったように、使うクォートで型が変わります。

> またバッククォート(`)を使っても文字列型になります。

> 'He said "madam, I\'m Adam."'

シングルクォートでも \' が使えるJS

> ダブルクォートとシングルクォートを使った文字列リテラルは、文字列の途中で改行できません。改行を入れたい場合は、\nなどの改行シーケンスを入れる必要があります。

> バッククォート`で囲んだ文字列はテンプレートリテラル(template literal)と言います。テンプレートリテラルは、改行と式の挿入(expression interpolation)ができます。式の挿入は${式}のように書きます。

> `現在、${count}名が見ています。`

> 基本的に"を使用する。文字列の中に"が含まれる場合は'を使用する。文字列展開する必要があるときは`を使用する。

nullがたまできたが、まだまだ方があるなあ 2022/02/14 23:17


TSのもふくめ15こあるみたい

> typeof null; //=> "object"

> 戻り値のない関数はundefinedになりますが、TypeScriptで戻り値なしを型注釈で表現する場合、undefinedではなくvoidを用います。詳しくは関数の説明をご覧ください。

> undefinedは「値が代入されていないため、値がない」、nullは「代入すべき値が存在しないため、値がない」という微妙な違い

> もしどちらを使うべきか迷ったらundefinedを使っておくほうが無難です

> nullは自然発生しない。undefinedは言語仕様上、プログラマーが明示的に使わなくても、自然に発生してくるものです。 

> undefinedもnullもプリミティブ型の値という点は共通していますが、undefinedは変数でありnullはリテラルです。 

> JSON
オブジェクトプロパティの値にundefinedを用いたとき、そのオブジェクトをJSON.stringifyでJSON化したときに、オブジェクトプロパティは削除されます。一方、プロパティの値がnullのときは、JSON化したときに値が保持されます。

> console.log(JSON.stringify({ foo: undefined }));

{}
console.log(JSON.stringify({ foo: null }));

{"foo": null}


> 特にこだわりがないのなら、typescriptではnullは使わずにundefinedをもっぱら使うようにするのがお勧めです。

>  実際にtypescriptの開発チームでは「nullは使わない」というたった1行のシンプルなガイドラインを示し、数多くの開発者が参加しやすくなるようにしています。 

undefined はそこら中で発生するので、undefinedに統一するのが簡単 2022/02/14 23:41

30分読んだのでおわり null/undefined まで

今日6項目進んだ あと178項目ある
 このペースだと30日かかる
  うーん、速度アップがいるかも…??

ーーーー

2022/02/15 22:29 残り178項目

加速する

1日25項目
 今日は配列リテラルまで

> Rubyのシンボル的なことは、JavaScriptやTypeScriptでは文字列を用いて解決します。

bigint
const x = 100n;

> bigintリテラルをTypeScriptで用いるには、コンパイラーオプションのtargetをes2020以上にする必要があります。

> const y = BigInt("9007199254740991");

BigInt(100) でも

小数はBigIntにはないよ

自動キャストのことが型強制(type coercion)
Stringとかはラッパーオブジェクトで自動ボックス化で活躍

ラッパーオブジェクト型じゃなくてプリミティブ型をつかってくのがよさそうだね

いま 4つ読んだ2022/02/15 22:50

> TypeScriptでは暗黙のanyを規制するオプションとして noImplicitAny が用意されています。tsconfig.json にて noImplicitAny: true を設定することで、TypeScriptが型をany型と推測した場合にエラーが発生するようになります。

> 理由なくanyを使うのは問題ですが、どうしてもanyを使わないとならない場面や、型安全性を妥協した上で、まずは動くコードを形にすることを優先するといったこともありえます。anyをどこまで許容するか、型チェックをどこまで厳格にするかは、チームの熟練度やプロジェクトの方針によるところが大きいです。

> 実際に慣れない頃はコンパイルエラーが出ている原因を調べて解消するのに1日を費やす場合もあります。

> 「がんばらないTypeScript」

オブジェクトまでで7つおわった あと18

> オブジェクト型には、クラスから作ったインスタンスだけでなく、クラスそのものや配列、正規表現もあります。

jS中級者なので知ってる話がおおい 結構はやい

> オブジェクトリテラルがあるおかげで、JavaScriptでは自由度の高いコードが書けるようになっています。

> JSONJavaScript Object Nation

Nationって何?

1ページが短いのではやいかも
  800文字くらい
25項目なら 20000文字 文庫本40ページ分

> let box: { width: number; height: number };

みたいに型注釈する ; がポイントっぽいかな?

> // 型エイリアス
type Box = { width: number; height: number };
let box: Box = { width: 1080, height: 720 };

もある

> let calculator: {
  sum(x: number, y: number): number;
};

> let calculator: {
  sum: (x: number, y: number) => number;
};

もある

> let box = { width: 1080, height: 720 };

で勝手にnumber になる (型推論)

> メソッドの場合は引数の型注釈は必要です。


> let foo: Record;

stringがキーで、 numberがバリューなプロパティを何個もいれたオブジェクトを定義できる

オブジェクトの型注釈 https://typescriptbook.jp/reference/values-types-variables/object/type-annotation-of-objects は大事そうだった

あと 14項目

> let obj: {
  readonly foo: number;
};

とかある

readonlyの項目長い


> let obj: Readonly<{
  a: number;
  b: number;
  c: number;
  d: number;
  e: number;
  f: number;
}>;

で、全プロパティ readonly な a,b,...f プロパティをもつオブジェクトをつくれる

> ユーティリティ型

> let size: { width?: number };

オプショナル

あと11 2022/02/15 23:28


> let obj: {
  [K: string]: number;
};

で、キーが string, 値が numberなプロパティをいくつでもつけられる

> インデックス型のフィールド名の型はstring、number、symbolのみが指定できます。

TypeScript特有の事項が多くなってきた

> let obj1: { [K: string]: number };
let obj2: Record;

おなじ

> const dangerousButton = Object.create(button);
複製用メソッドがある(中級者にもかいてあったかも)

> JavaScriptの開発には次のような要件がありました。ブラウザで動く言語で、構文はJava風に。しかし、Javaほど大掛かりでないようにと。そして、開発期間はというと、10日と逼迫したものでした。

> JavaScriptの開発にあたり、Selfという言語の影響があったとEich氏は言います。

> JavaScriptのプロトタイプベース採用の背景には、言語をシンプルで柔軟なものにしたいという考えが根底にあったわけです。

その結果いろいろな書き方が生まれた(これが柔軟らしい)

> let b: Object;
let c: {};

という書き方もある

> Object型はインターフェース

自動ボックス化で プリミティブ型もOKになる

あと7つ 2022/02/16  0:02

分割代入も入れ後にできる

分割代入に名前の付け替えがある
>   canada: { name: canadaName },

https://typescriptbook.jp/reference/values-types-variables/object/destructuring-assignment-from-objects

オブジェクトのキーと変数名が同じだと、変数名を指定してその名前のキーにその値をいれられる

> const pikachu: Wild = { name, no, genre, height, weight };

> JavaScriptのオプショナルチェーン?. 

便利そう

> const title = book?.title;

titleがなかったら undefined になる

> 関数を呼び出すときにもオプショナルチェーンが使えます。関数に使う場合は、引数カッコの前に?.を書きます。

> const result = increment?.(1);

> 配列要素を参照する際にもオプショナルチェーンが使えます。要素を参照する場合は、カギカッコの前に?.を書きます。

> const title = books?.[0]; 

Null合体演算子と組み合わせると便利

> const title = book?.title ?? "デフォルトタイトル";

> for (const prop in foo) {

propにはキーが入る

>   if (Object.prototype.hasOwnProperty.call(foo, prop)) {

ってやると安全

> for (const [key, value] of Object.entries(foo)) {
> for (const key of Object.keys(foo)) {
> for (const key of Object.values(foo)) {
でも hasOwnProperty いらず


構造的部分型にきたぞ 2022/02/16  0:36

https://typescriptbook.jp/reference/values-types-variables/structural-subtyping

構造的部分型で置換できちゃうから、うっかり動いてしまわないように注意、ってことでは?

終わり 2022/02/16  0:41
 2時間強かかってるが?

ーーー

明日は

配列の型注釈から
https://typescriptbook.jp/reference/values-types-variables/array/type-annotation-of-array

if-else 文まで

型がおわったらJSっぽいからすぐ終わっていきそう

2022/02/16 17:44 再開

2022/02/16 18:21 ほんとうに再開

> let array: number[];
> let array: Array;

2通りある

> プロジェクトでは統一すべし

> JavaScriptの配列はオブジェクトであるため、配列の中身が同じでも、オブジェクトのインスタンスが異なると==では期待する比較ができないので注意が必要です。この点はPythonのリストと同じです。

> このような配列の中身を比べるための演算子やメソッドはJavaScriptにはないため、中身を比較したいときにはlodashのisEqualなどのパッケージを使うのがお勧めです。

> ブラケット[]

> JavaScriptの配列では、存在しないインデックス番号でもアクセスできます。その場合でも、JavaScriptではエラーになりません。得られる値はundefinedになります。

なんか、他言語いずれかでのことを知ってる人向けの資料だね

> string[]型から0番目の要素の型はstringになります。

> 要素アクセスで得た値はstringとundefinedどちらの可能性もありながら、TypeScriptは常にstring型であると考えるようになっています。そのため、要素アクセスでundefinedが返ってくる場合のエラーはTypeScriptでは発見できず、JavaScript実行時に判明することになります。

> この問題を指摘してもらうようにするには、コンパイラーオプションのnoUncheckedIndexedAccessを有効にします。

> string | undefined型のままではtoUpperCaseなどの文字列型のメソッドは呼び出せません。そこで、if文で変数が文字列型だけになるように絞り込みます。

複雑になってきた

> if (typeof character === "string") {

> 配列要素へのアクセスを安全にするために、noUncheckedIndexedAccessを有効にしておくことを推奨します。

> const nums: readonly number[] = [1, 2, 3];
> const nums: ReadonlyArray = [1, 2, 3];


型アサーション as number[];

分割代入辺 2022/02/16 20:38 戻ってきた
https://typescriptbook.jp/reference/values-types-variables/array/destructuring-assignment-from-array

> const [one, two, three] = oneToFive;


> noUncheckedIndexedAccess

では number | undefined になってしまう

> ネストした要素の分割代入の書き方は、ネスト構造と一致するようにブラケット([ ])を重ねます。

> const [, , , four, five] = oneToFive; 


> const [one, ...rest] = oneToFive;

残りが残余パターンでまとまる

> 残余部分の型は配列のnumber[]になります。


ぜんぶ JS中級者でみたメソッドなのだ

> reverse   配列の要素を逆順に並び替える 

便利そう


> const copy = [...original]; // コピーを作る

> const reversed = [...original].reverse();


あと19項目 2022/02/16 20:48 (ループする方法から)


> for (const value of arr) { 

配列だと要素が入る

> forEachには戻り値がありません。for文などと異なり、breakやcontinueは使えません。

 > arr.forEach((value, i) => {

インデックスもとれるぞ

> const arr2 = arr.map((value) => value + value); 

> mapではbreakやcontinueは使えません。

> const concated = [...arr, ...arr2]; 

連結も簡単

> 似たシンタックスとして分割代入で使われる残余パターンの構文がありますが、異なる構文なので注意が必要です。

分割代入の残余パターンとは別


> TypeScriptの配列の型は共変(covariant)です。

> 共変とはその型自身、もしくは、その部分型(subtype)が代入できることを言います 共変であれば、Animal型の変数にはAnimal自身とその部分型のDogが代入できます。

> type Animal = { isAnimal: boolean };
type Dog = { isAnimal: boolean; isDog: boolean };


> TypeScriptが健全性(soundness)と利便性のバランスを取ること目標にして、型システムを設計しているためです。配列が非変であると健全性は高くなりますが、利便性は下がります。

危険だが、便利らしい

> const list: [number, string, boolean] = tuple(); 

配列の各要素の型ッ指定できるタプル

> function tuple(): [number, string, boolean] { 

> 配列の型はarray(T[]), generic(Array)というふたつの書き方がありました 

> const [num, str, bool]: [number, string, boolean] = tuple();
> const [, , bool]: [number, string, boolean] = tuple();

分割代入をかつよう

> Promiseという型の変数はawaitをその前につけるとTが取り出せる 


> const tuple: [string, number] = await Promise.all([
  takes3Seconds(),
  takes5Seconds(),
]);

なるほど

> Promise.all()は先に終了した関数から順番に戻り値のタプルとして格納されることはなく、元々の順番を保持します。



あと15項目 2022/02/16 21:03 次は列挙型

enum

> enum Position { 

TypeScriptにしか enumはないのかな? そうらしい

> 値は0からの連番になります 

> let position: Position; 

> enum Position {
  Top = 1, // 1

とかもある

> enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}

もあるぞ

列挙型はTypeScript独自なのでオススメできないらしい


> 型に関する部分を除けば、JavaScriptの文法から離れすぎない言語になっています。

> 文字列列挙型は例外的に公称型になります。 

> type YesNo = "yes" | "no";

とかオススメらしい

type 宣言 キーワードさらっとでてきたっぽい



> const yes = Symbol();
const no = Symbol();
type YesNo = typeof yes | typeof no;

とかも

> type Position = typeof Position[keyof typeof Position];

むふう


次はユニオン型 あと11項目 2022/02/16 21:10

>  |は型のリストの冒頭に置くこともできます。型ごとに改行するときに、列が揃うので便利です。


type ErrorCode = | 400 | 401;
値を型にすることもかのうだったね


> type List = (string | number)[];

() をつけましょう

> 絞り込み(narrowing)

> if (typeof maybeUserId === "string") {

tsでおなじみの構文


> 判別可能なユニオン型

> オブジェクト型からなるユニオン型を絞り込む際に、分岐ロジックが複雑になる場合は、判別可能なユニオン型を使うとコードの可読性と保守性がよくなります。

>   if (status.done === false && "progress" in status) {

とかでも型を絞り込める
    

この項目長い 4800字

なんか大物が続きそうだ

> タグ付きユニオン(tagged union)や直和型と呼ぶこともあります。


> 各オブジェクト型を判別するためのプロパティ(しるし)を持つ

    このプロパティのことをディスクリミネータ(discriminator)と呼ぶ

> type InProgress = { type: "InProgress"; progress: number };

とか

というか、

> type UploadStatus = InProgress | Success | Failure;
type InProgress = { type: "InProgress"; progress: number };

後で中身を定義してもいいんだね

文字列もリテラルがたナンだね
 文字列 数値 論理値


> nullと非nullの関係にある型もディスクリミネータになれます。
> type Result = 
  | { error: null; value: string } 
  | { error: Error };

片方はnullにならないなら オブジェクト型とかでもいいみたい
undefined もあるよ

> ディスクリミネータを変数に代入し、その変数を条件分岐に使った場合も、型の絞り込みができます。


型のある言語でここまで型のことをちゃんとやってたかな??
 でもそういう機能もあったような気もする


オブジェクトの定義を合成させるインターセクション型 2022/02/16 21:28

> type ThreeDimensionalPoint = TwoDimensionalPoint & Z; 

> プリミティブ型のインターセクション型をつくることもできますが、作るとneverという型ができます。意外なところで役に立ちます。

Required Partial 便利そうだね

> type Optional = Partial<{
  index: number;

> type Parameter = Readonly;


あと8項目 次は型エイリアす e0c 2022/02/16 21:32

> type StringOrNumber = string | number;

さっきからたくさん出てきてる

> stringなどのビルトインの型

> // リテラル型
type OK = 200;

> // 関数型
type CallbackFunction = (value: string) => boolean; 

関数型もまだ染み付いてないけどきいじそう


> 型エイリアスは同じ型を再利用したいときに使うと便利です。型の定義が一箇所になるため、保守性が向上します。

読みやすくもなる(ことがある)


> TypeScriptには、型推論を上書きする機能があります。その機能を型アサーション(type assertion)と言います。

> const strLength: number = (value as string).length;

numberにも 同じ名前のメソッドがあると 型に従ってエラーを出せずピンチ

> const strLength: number = (value).length;


> アングルブランケット構文はJSXと見分けがつかないことがあるため、as構文が用いられることのほうが多いです。

やはり複数の書き方があるJSの子供であるTS

> それでも自分の書いた型アサーションが正しいという場合は、unknown型を経由することで上のようなエラーを出さないようにもできます。

> 型アノテーションはキャストではないため、TypeScriptでは型アノテーションをキャストとは呼ばないことになっています。実行時に型変換をするには、そのためのロジックを書く必要があります。 

コンパイルときにしか聞かないからキャストではないとのこと

> 型に関することはできるだけ、コンパイラーの型推論に頼ったほうが安全なので、型アサーションは、やむを得ない場合にのみ使うべきです。

型アサーションを使う必要が出てきたら、それよりも先に、型ガードやユーザー定義型ガードで解決できないか検討してみるとよいでしょう。

> let value: number;

がカた注釈


> オブジェクトリテラルの末尾にas constを記述すればプロパティがreadonlyでリテラルタイプで指定した物と同等の扱いになります。i

> const pikachu = {
  name: "pikachu",
  no: 25,
  genre: "mouse pokemon",
  height: 0.4,
  weight: 6.0,
} as const;


全部を一括でこていできて便利


あとご項目 2022/02/16 21:41 次は definite assignment assertion


> let num!: number;
//     ^definite assignment assertion
> この変数はこの型であることが確実であることをTypeScriptコンパイラに伝えるということです。

> console.log(num! * 2); // エラーにならない
//             ^非Nullアサーション


> // 型ガード
if (typeof num === "number") 

>   return value !== null && typeof value === "object";

> ここで説明したのはJavaScriptのtypeof演算子です。TypeScriptのtypeof型演算子については、typeof型演算子の説明をご覧ください。

別の typeofがあるらしい

> JavaScriptにはグローバルオブジェクト(global object)と呼ばれるオブジェクトがたったひとつ存在します。ブラウザではwindowオブジェクトがグローバルオブジェクトです。 

全てのグローバル変数を司るグローバルオブジェクト

> グローバル変数は、グローバルオブジェクトのプロパティになります。

> 日付のDateクラスや、デバッグに使うconsoleオブジェクトなどの組み込みAPIはすべてwindowオブジェクトのプロパティです。

> レキシカルスコープ(lexical scope)変数とは、関数を定義した地点から参照できる、関数の外の変数を言います。

> ブロックスコープはif構文などのブレースにも作用します。条件分岐の中で変数宣言された変数は、条件分岐の外からは参照できないので注意しましょう。

> ローカル変数を宣言する場合は、letやconstを用いますが、これを書き忘れた変数代入は、グローバル変数になってしまいます。 TypeScriptでは変数宣言されていない変数に代入しようとすると、コンパイラが指摘してくれます。

> else ifのようにelseとifの間にはスペースが必要です。

> JavaScriptのif-elseは文です。式ではないので、条件分岐を直接変数に代入することはできません。

居ょの文おわり 2022/02/16 22:24

明日は this引数まで

wwwwwwww

2022/02/17 21:47

よんでこ

https://typescriptbook.jp/reference/statements/ternary-operator から

> for-of文 - 拡張for文

for-of が 拡張for文 ということらしい

> for (const [index, word] of words.entries()) {

インデックスと値を一緒に取る方法
 
> switch (条件) {
  case 値A:
    値Aの処理;
    break;

switch のあとに { があって結構珍しい書き方?

> switchのフォールスルー問題

PHPと同じかな?

> TypeScriptでは、コンパイラオプションnoFallthroughCasesInSwitchをtrueにすると、フォールスルーを警告するようになります。このオプションは有効化しておきましょう。

fallthrough できなくなるらしい

> caseの変数スコープはない

>   case 1: {

{ で囲める case


> 例外として投げるオブジェクトはErrorオブジェクトを使うのが一般的です。

Error 以外も投げれそう


> Errorオブジェクトを使ったほうがコードの読み手に意外性を与えないからです。加えて、スタックトレースが追えるのはErrorオブジェクトだけだからです。

意外性最小を目指そう

> TypeScriptではcatchの変数の型はデフォルトでany型になります。

> JavaScriptとTypeScriptではcatchは1つしか書けません。JavaScriptでエラーの型によってエラーハンドリングを分岐したい場合は、catchブロックの中で分岐を書く方法で対応します。

>   } else if (e instanceof RangeError) {

> 唯一never型は代入できます。

> const foo: never = 1 as never;

> never型はどんな型にも代入できます。

> never型の「値が無い」とはどういうことでしょうか。たとえば、例外が必ず発生する関数の戻り値です。戻り値は絶対に取れません。そのため、戻り値の型はnever型になります。

> 終了しない関数も戻り値がnever型になります。

ずっとまわりそう


never型ながい 3600時


void型はundefinedが代入できますが、neverは値を持てません。
意味的に戻り値でのvoidとneverは、戻り値が無い点は同じです。関数が終了するかが異なります。voidは関数が最後まで実行されるという意味です。neverは関数の処理が中断、もしくは、永遠に続くことを意味します。

網羅性チェックに使えるらしい 上級ュ者むけっポイ感じする

> 一歩進んで網羅性チェック用の例外クラスを定義するのがお進めです。このクラスは、コンストラクタ引数にnever型を取る設計にします。

            
> 網羅性チェックを例外にしておくと、未使用変数についてのコンパイルエラーが発生しなくなります。

バッドプラクティス感はある

> このような型チェックのコードを型ガードと呼びます。
> if(typeof month === "string")

よくみるやつ


> date != nullの型ガードを追加することで型エラーを解消できます。
| null のばあい

>  特定のクラスのインスタンスであることを判定する型ガードを書きたい場合はinstanceofを利用します。

クラスの判定もできるTypeScript

> 特定のクラスのインスタンスであることを明示せず、in演算子でオブジェクトが特定のプロパティを持つかを判定する型ガードを書くことで型を絞り込むこともできます。

>   if ("castMagic" in player) {


> 型ガードはインラインで記述する以外にも関数として定義することもできます。

> function isWizard(player: Player): player is Wizard {

便利

> unknownはどんな型も代入できる型

> unknown型はanyを除いて他の型には代入できない

> 同様にunknown型は、プロパティアクセスや関数呼び出しがコンパイルエラーになる。

あと 16項目 2022/02/18  1:06

any, unknown型はどのような値も代入できます。

any型に代入したオブジェクトのプロパティ、メソッドは使用することができます。

> noImplicitAnyがあります。既存のJavaScriptのプロジェクトをTypeScriptに置き換えていくのではなく、スクラッチの状態からTypeScriptで作るのであればこの設定を入れるとよいでしょう。

僕も知ってる設定

> 関数宣言

定まさし

あと14項目 2022/02/18  1:11

引数の型注釈を省略した場合、コンパイラーはany型と暗黙的に解釈します。
コンパイラーオプションのnoImplicitAnyをtrueに設定することで、引数の型注釈を必須にできます。


型推論で ユニオン型になることも

> 関数式を用いて関数を定義するには、function式を用います。関数式は式なので、関数の終わりにはセミコロンを書きます。

; をつけるだけで function敷になる

> アロー関数は関数式に比べて短く書けるのが特徴的です。引数が1つだけの場合は、引数のカッコが省略できます。

色んな書き方があるJS

> さらに、関数内のコードが式1つだけの場合は、ブレースとreturnが省略できます。

シンタックスシュガーだらけ

> アロー関数でカッコを省略した記述をした場合には、引数と戻り値のどちらも型注釈を書けません。

noImplicitAnyが有効になっていても、関数引数に直接アロー関数を書く場合は型注釈を省略できます。

TypeScriptでは、関数の型を宣言できます。関数の型の宣言とは、関数の実装を示さずに、関数のインターフェースを定義することです。

type Increment = (num: number) => number;

> しかし、関数宣言(function文)の型注釈には使えません。

なんでや function敷には使える

> 関数の型宣言を型注釈に使った場合、関数の実装側の引数と戻り値の型注釈は省略できます。 実際のコードでは、省略形で書くのが一般的です。


> TypeScriptでは、アロー関数構文で関数の型を宣言する方法とは別に、メソッド構文でも関数の型を宣言できます。

> // メソッド構文による型宣言
type Increment2 = {
  (num: number): number;
};

> 一般的には、アロー関数構文で型宣言します。アロー関数構文のほうが短くシンプルだからです。

> メソッド構文による型宣言は、オーバーロード関数の型宣言に使われることがあります。

> TypeScriptでは、関数の実装から関数の型を宣言できます。関数の値に対してtypeof型演算子を使います。

> JavaScriptの関数宣言と関数式の違いが現れるひとつの例は巻き上げ(hoisting)です

関数宣言には巻き上げがあり、関数式には巻き上げがありません。

このコードは、hello関数の定義行より前でその関数を呼び出しているのに、エラーにはならず問題なく"Hello World"が出力されます。これは関数宣言には巻き上げがあるためです。


残り9項目 ニ地2022/02/18  1:36

他の言語では関数は特別な立ち位置のことがあります。ある言語では、同じ名前の変数を定義してもエラーにならないのに対し、同じ名前の関数定義はエラーになります。またある言語では、関数を変数に代入できなかったりします。

JavaScriptの関数は値です。つまり、PHPのような他の言語と比べると特別扱いの度合いが少ないです。

JavaScriptで関数の再代入によるバグを未然に回避したい場合は、constと関数式を組み合わせます。関数式については後述します。

ちなみに、TypeScriptではコンパイラーが重複した関数宣言を警告してくれるので、バグの心配はありません。

関数は値なので、関数名のスコープも変数と同じようにスコープの概念があります。たとえば、関数スコープの中で定義された関数は、そのローカルスコープでのみ使うことができます。


https://typescriptbook.jp/reference/functions/function-is-an-object
1行だけでめちゃみじかい 50地


あと6項目2022/02/18  1:49

TypeScriptで戻り値がない関数の戻り値を型注釈するにはvoid型を用います。void型は関数の戻り値を型注釈するためにある特別な型です。


> JavaScriptでは引数が少ない時はその引数にはundefinedが渡され、引数が多い場合は余分な引数は無視されますがここはTypeScriptとJavaScriptとの大きな違いです。

> 引数を省略したいことがあります。そのときはオプション引数とデフォルト引数を使用することができます。

> 可能であればデフォルト引数の使用を検討してください。

> オプション引数は必ず最後に書かなければいけません。つまり、次のようにオプション引数より後ろに普通の引数を書くことはできません。

デフォルト引数とは、関数に値が渡されないときやundefinedが渡されたときに代わりに初期化され使用される値のことです。なおnullが渡されたときはデフォルト引数は適用されませんので注意してください。

> const p0: Point = {
  x: 0,
  y: 0,
};
function distance(p1: Point, p2: Point = p0): number {

 オプション引数と比べてもより簡素に書けるようになります。

また、オプション引数と異なりデフォルト引数は値が渡されたときも渡されなかったときも意図する型(この場合Point型)が入っているのでオプション引数と異なり処理の分岐が不要になります。

> さらに、デフォルト引数があることでデフォルト引数を受け付けている引数は型推論が効き型を書く必要がなくなります。

なるほど、だから引数に方がかかれてないことがあったのね

> function distance(p1: Point, p2: Point = inverse(p1)): number {

もかのう

> デフォルト引数はオプション引数と異なりその引数を最後に書く必要はありません。

イタレリツクセリなデフォルト引数

> distance(undefined, q2);

> 関数をデフォルト引数として使うときは非同期の関数を使うことができません。

こういうところで化まりそう でもまぁ エラーメッセージがあるので大丈夫とは思う

引数の個数が決まっていない引数のことを可変長引数(variable length arguments, variadic arguments)といいます。JavaScriptでは可変長引数は残余引数(rest parameter)と呼びます。

function func(...params) {

受け取った残余引数は配列になります。
残余引数は必ず最後の引数でなければなりません。残余引数を複数持たせることはできません。また、残余引数の後に普通の引数を置くこともできません。

JavaScriptに組み込みのメソッドにMath.max()があります。これは、引数に与えられた数値の中から最大値を返します。この関数は残余引数を要求します。

関数呼び出しのときにひとつの配列にまとめて渡すことはできません。
配列を余剰引数に渡す場合は、スプレッド構文(spread syntax)を用います。スプレッド構文は...と書きます。

const highest = Math.max(...scores);

残余引数もスプレッド構文も...と同じ表記ですが、スプレッド構文は配列を引数にバラすものです。

アロー関数以外の関数とクラスのメソッドの第1引数はthisという特殊な引数を受けることができます

> 引数のthisを指定することによって意図しないメソッドの持ち出しを避けることができます。 
そうなんや

おわり 2022/02/18  2:29

やっぱり二時間くらい?
 もっとかかってるかも ながら

明日は
メソッド戻り型のthis型 まで
 やっぱ26項目にしようか
  ◎クラスの継承まで でかそう
   まぁ速度重視、ってことで
あと103こうもくなので 4日でおわり 
つまり やはり 2/21(月)におわる
 その次の日にこれをブログにしたい

wwwwwwww

2022/02/18 23:25

分割代入引数から
https://typescriptbook.jp/reference/functions/destructuring-assignment-parameters

> JavaScriptでは分割代入構文は関数の引数でも使えます。



> function foo({ a, b }) {
> foo({ a: 1, b: 2, c: 3 });

プロパティをそのまんま入れられる感じっぽい

> function foo({ a: x, b: y }) {

> 配列の分割代入引数は、カギカッコの中に配列要素を代入する変数名を書きます

> function bar([a, b]) {

> bar([1, 2, 3]);

> function foo({ a, b }: { a: number; b: number }) {}
> function bar([num1]: number[]) {}

> function bar([num1, num2]: [number, number]) {} 

2つ指定するのがタプル型 多分

JavaScriptでは、分割代入引数に対応するオブジェクトプロパティや配列要素が無い場合、undefinedが代入されます。一方、TypeScriptでは分割代入引数に対応するオブジェクトプロパティや配列要素が無いと、コンパイルエラーになります。

{} や [] がひきすうになるのが分割代入引数

function foo({ a = 0 }) {

function foo({ a = 0 }: { a?: number | string }) {}

?がいるデフォルト引数には

プロパティの既定値からプロパティの型が予想できる場合、型注釈を省略できる場合もあります。

function foo({ a, b } = { a: 0, b: 0 }) {

引数全体が無い、または、undefinedの場合に採用されます。

bar([1]);

1 undefined

function foo({ a }: { a?: number } = { a: 0 }) {}

> JavaScriptでは、分割代入引数の引数名と同じ変数が定義済みであれば、オブジェクトリテラルのプロパティ名を省略し、変数だけ渡すことができます。

よくみる

> bmi({ weight, height });

長い項目多い
 かんすうのコーナーの中

> JavaScriptやTypeScriptの関数には、Pythonにあるキーワード引数のような機能はありません。その代わり、分割代入引数を応用することで、キーワード引数と同じようなことができます。


python
func(x=1, y=2, z=3)  # => 1 2 3

べんり

キーワード引数と同じような機能はRubyや、Scalaの名前付き引数(named argument)などに見られます

Ruby にあるんだ

Options Objectパターンというデザインパターン

> Options Objectパターンは複数の位置引数を受け取る代わりに、ひとつのオブジェクトを引数に受け取るように設計された関数を言います。

よくみる

func({ x: 1, y: 2, z: 3 });

さらに、Options Objectパターンでは分割代入引数を応用すると、引数の部分をよりシンプルに書けるようになります。

function func({ x, y, z }) {


function func({ x, y, z }: { x: number; y: number; z: number }) {

でも呼び出し側が長くなるね
findUsers({ country: "JP", city: "Tokyo", order: "id", sort: "asc" });

関数宣言側をfunction func({ hoge })に変更する代わりにfunction func({ hoge: fuga })のようにします。

> function func({ x, y = 0, z = 0 }: { x: number; y?: number; z?: number }) {

オプショナルなので?

> function func({ x = 0, y = 0, z = 0 }: Options = {}) {

0を入れられてすごい


> function isDuck(animal: Animal): animal is Duck {

なんか便利そう


アサーション関数
> こちらは例外を投げるかどうかで判定します
>   throw new Error("YOU ARE A FROG!!!");


オーバーロード
> TypeScriptもこの機能を用意しているのですが、大元がJavaScriptであることが災いし、やや使いづらいです。


あと20項目 いまSwpw*オーバーロード


> type Distance = {
  (p: Point): number;
  (p1: Point, p2: Point): number;
  (x: number, y: number): number;
  (x1: number, y1: number, x2: number, y2: number): number;
};


複数の定義ができる


> rejectをするには例外を投げる

中級者でよんだ

>awaitはasync関数の中でしか使えないこと

> トップレベルawaitは触れなくていい

中級者にかいてあった感


いま paa 2022/02/19  0:25

あと15項目

ここで注目するべきはrequest1()関数の戻り値をPromiseと型指定をしている箇所です。
TypeScriptでPromiseの型を指定する場合はPromiseと書きます。TにはPromiseが解決(resolve)された時に渡す値の任意の型を指定します。

async /awaitが存在します。
この構文を利用することで、非同期処理をより同期処理と同じような文脈で書くことができるようになります。

> 関数の前にasyncキーワードをつけることで、その関数は非Promiseの値を返す時にその値を解決したPromiseを返すようになります。Promiseをそのまま返すことも可能です。二重にPromiseがラップされることはありません。

なるほど


> TypeScriptでは、クラスを定義するとクラス名と同じ名前の型が同時に定義されます。

あよ12項目 2022/02/19  0:45

constructor構文
フィールドは宣言時に型を省略した場合でもコンストラクタで値が代入される場合は、代入する値で型が推論されます


あと10高銀 2022/02/19  0:53


> TypeScriptでは、初期化子(initializer)を使うとインスタンスのフィールドの初期値を指定できます。

便利 2022/02/19  0:56

初期化子で値の型が自明な場合、TypeScriptコンパイラーはフィールドの型を推論してくれます。そのため、初期化子を伴うフィールドは型注釈を省略できます。

TypeScriptにはJava風のアクセス修飾子があります。

nameプロパティはpublic宣言されているため、インスタンスされた変数(gorilla)からの読み書きが可能になっています


privateメソッドの多くの使い方としては、自身のクラス内の長いコードを機能別に分ける時に利用します。

メソッドの引数にはアクセス修飾子を設定することはできませんがコンストラクタは特別です。

public  自身のクラス内、継承クラス、インスタンス化されたクラスのどれからでもアクセス可能

読み取り専用フィールドは、コンストラクタかフィールド初期化子でのみ値を代入できます。

クラスはオブジェクト
一方、TypeScriptでは型安全のためにこうした動的な拡張ができないようになっています。

あと4項目 2022/02/19  1:09

TypeScriptでは、Java風の静的フィールドの書き方ができるようになっています。TypeScriptで静的フィールドを宣言するにはstaticキーワードを用います。

  static field: number = 123;
  static field = 123;

TSってJSをだいぶJavaふうにしてるんだね
  private static field: number;
  static readonly field: number;

readonly static メソッドなどはない


fluent interfaceとは「流れるようなインターフェース」という意味で、method chaining(メソッドの連鎖)という小技を使って、可読性の高いコードを実現するメソッドの作り方のことです。


  protected value: number;

に入ったものが勝手にかえるというか this が this.value と評価される感じ

return thisでチェインできる

>   public subtract(value: number): this { 

とすると継承しても安心


> サブクラスにコンストラクタを書く場合、スーパークラスのコンストラクタは必ず呼び出す必要があります。スーパークラスのコンストラクタはsuper()で呼び出します。 

中級者でみた

2022/02/19  1:19 よみおわ



https://typescriptbook.jp/reference/object-oriented/class/class-inheritance

2022/02/20  1:58

今日は Readonly まで

> TypeScriptでは、クラスに1つでも非パブリックなプロパティがあると、そのクラスだけ構造的部分型ではなく公称型(nominal typing)になります。

なるほど

> TypeScriptにはabstract修飾子があり抽象クラスを表現できます。
抽象クラスとは直接インスタンス化(new)することができず、必ずスーパークラスとして利用することを保証するものです

> 抽象クラス内のメソッドにもabstract宣言を行うことができます。interfaceと同じようにサブクラスは抽象メソッドを実装する必要があります。

final sealed ない (継承付加にさせる)

もう4つ終わった 2022/02/20  2:05

JavaPHPなどの言語では、インターフェースが定義できますが、JavaScriptにはそれに相当する構文がありません。一方、TypeScriptにはインターフェースがあります。

interface SomeInterface {

なるほど便利 だけどJSとはどんどんべつにナッテくね
 interface/ ができそう

TypeScriptではメソッドだけでなく、パブリックフィールドも定義できます。

TypeScriptは構造的部分型なので、インターフェースと実装関係がないオブジェクトの型注釈としても利用できます。

const taro: Person = {

組み込みapiで 13
 
class Developer implements Human {

class TypeScriptProgrammer implements Human, Programmer {

TypeScriptでは、extendsキーワードを利用して定義済みのインターフェースを継承して、新たにインターフェースを定義することができます。

プロパティを部分型に宣言しなおす
ある型からその型のリテラル型にすることも、ユニオン型から部分的に選択することもTypeScriptではそれぞれサブタイプにしていることと同じ意味があります サブクラスにすることもできます。

interface IndexPage extends WebPage {
  path: "/";

ES2016.array.ts

> type Array = ES2016Array & ES2019Array; 


インターフェイス判定をするには型ガードを自前で実装する必要があります。以下はその例のisStudent()です。

インターフェースは型の宣言であり、型エイリアスは型に名前をつける機能です。この定義に立ち返って使い分けをしましょう。

ジェネリクスもないJavaScript

はんぶくくきた 2022/02/20  2:40
つかれるまでやろうか

MapはJavaScriptの組み込みAPIのひとつで、キーと値のペアを取り扱うためのオブジェクトです。Mapにはひとつのキーについてはひとつの値のみを格納できます。

const map = new Map();

長い

https://typescriptbook.jp/reference/builtin-api/map
5900地

コンストラクタにキーと値の[タプル型][K, V]の配列[K, V][]を渡すとMapオブジェクトが作られます。

Mapの型変数を省略した場合、TypeScriptはコンストラクタ引数からMapの型を推論します。

コンストラクタ引数を省略した場合、空のMapが作られます。

function doSomething(map: Map) {}

めちゃ使いそう

そのため、Mapはnullとundefinedを異なるキーとみなします。

NaN同士は厳密等価ではありませんが、例外的に同じキーとみなされます。

等価と厳密等価がある

オブジェクトは等価でも厳密等価でもないため、別のキーとみなされます。

たまに使いそう

Mapにキーと値のペアを追加するにはsetメソッドを使います。

map.set("a", 1);

getメソッドは、キーが存在しない場合、undefinedを返します。

deleteの戻り値は、キーが存在した場合true、そうでない場合falseになります。


> この場合、getで値を取得して、その値がundefinedでないことをチェックするとうまくいきます。 

Mapに登録されている要素をすべて削除するにはclearメソッドを使います。

keysメソッドはキーの反復可能オブジェクトを返します。
valuesメソッドは値の反復可能オブジェクトを返します。
entriesメソッドはキーと値の反復可能オブジェクトを返します。

よくみる

> for (const [key, value] of map) { 

とうろくされたzilyunn

const map2 = new Map(map1);
シャローコピー

MapをJSON化する場合は、一度オブジェクトにする必要があります。


const keyValues = [...map];
[["a", 1], ["b", 2], ["c", 3]]

> const map = new Map(Object.entries(obj));

オブジェクトがMapになる

const obj = Object.fromEntries(map);


この Map がおわったらあと12こう木 今日は

反復の順序が複座つなオブジェクト


メソッドで操作するMap、 言語仕様だから専用の書き方があるオブジェクト
  Mapは組み込みapi


一旦…最後までか? Errorまでか? 2022/02/20  3:01

Setもそこそこでかい
https://typescriptbook.jp/reference/builtin-api/set

2500地

Setには重複する値が格納できません。Setに格納された値は一意(unique)になります。


コンストラクタに配列を渡すと、値がSetに格納されます。


空のSetオブジェクトのTypeScript上の型はSetになります。これでは後からSetに値を追加できないので、空のSetを作るときは、Setの型変数を指定する必要があります。

const fruits = new Set();

Mapのキーな指板 Set

JSONにするとき
const array = [...fruits];
console.log(JSON.stringify(array));

「Setに渡した値は重複しない」という特性を使って、配列から値が重複する要素を取り除く処理に応用できます。

const array2 = [...new Set(array1)];


あと11項目 2022/02/20  3:04


TODO: 実務ではdate-fnsの使用を推奨する

ErrorはJavaScriptの組み込みAPIのひとつで例外を取り扱うためのオブジェクトです。

JavaScriptにもある

組み込みAPIとしてErrorには次のサブクラスがあります。

    EvalError
    InternalError
    RangeError
    ReferenceError
    SyntaxError
    TypeError
    URIError

便利そう

class CustomeError extends Error {

わかる

console.log(err.stack);

name と message を一気にだせて便利な .stack


もし捕捉した値があるクラスのインスタンスまたはある型であるかを判定したい場合はinstanceof, keyofあるいは型ガードを使います。

  if (e instanceof Error) {

モジュールは、importまたはexportを1つ以上含むJavaScriptファイルを言います。

ナウくて、前ははっきりと知らなかった部分

importなど export require めちゃなが
9000じ
https://typescriptbook.jp/reference/import-export-require
2022/02/20  3:37

export const foo = "foo";

JavaScriptのモジュールは、明示的にexportをつけた値だけが公開され、他のモジュールから参照できます

Javaなどの他の言語では、モジュール(パッケージ)のメンバーがデフォルトで公開になり、非公開にしたいものにはprivate修飾子をつける言語があります。そういった言語と比べると、JavaScriptは基本方針が真逆なので注意が必要です。


モジュールのコードが評価されるのは、1回目のimportのときだけです。2回目以降のimportでは、最初に評価した内容が使われます。言い換えると、モジュールは初回importでキャッシュされるとも言えますし、モジュールはいわゆるシングルトン(singleton)的なものとも言えます。

もしjQueryに依存するパッケージがあるとすれば、jQueryの宣言より下に書く必要があります。

パッケージが少なければまだしも、増えてくると依存関係が複雑になります。もしも読み込む順番を間違えるとそのhtmlでは動作しなくなるでしょう。

require()
Node.jsでは現在でも主流の他の.jsファイル(TypeScriptでは.tsも)を読み込む機能です。基本は次の構文です。


const package1 = require("package1");

このとき.js, .jsonとTypeScriptなら加えて.tsを省略することができます。TypeScriptでの開発においては最終的にJavaScriptコンパイルされることを考慮すると書かないほうが無難です。


.jsを.tsと同じ場所に出力するようにしているとTypeScriptにとって同じ名前の読み込ことができるファイルがふたつ存在することになります。このときTypeScriptは.jsを優先して読み込むので注意してください。

また指定したパスがディレクトリで、その中にindex.js(index.ts)があれば、ディレクトリの名前まで書けばindex.js(index.ts)を読み込んでくれます。

他のファイルを読む込むためにはそのファイルは何かを出力している必要があります。そのために使うのがこの構文です。

module.exports = (i) => i + 1;

const increment = require("./increment");

このmodule.exportsはひとつのファイルでいくらでも書くことができますが、適用されるのは最後のもののみです。

exports.increment = (i) => i + 1;

const util = require("./util");

console.log(util.increment(3));

const { increment } = require("./util");

console.log(increment(3));

const { increment: inc } = require("./util");

ES6で追加された機能のため、あまりにも古いブラウザでは動作しません。

require()はファイル内のどこにでも書くことができる一方でimportは必ずファイルの一番上に書く必要があります。

import * as package1 from "package1";
import package2 from "package2";

微妙に違う

export default (i) => i + 1;

node.js の require に default 的なやつと 名前付きのやつがあったので、 ES Moduleでも二通りアルンだね

まぁ、突っかかったときとかは https://typescriptbook.jp/reference/import-export-require を読み返そう

2022/02/20  3:54


> ES Moduleではimportをファイルの先頭に書く必要があります。これは動的に読み込むファイルを切り替えられないことを意味します。このimport()はその代替手段にあたります。 

require()と異なる点としてはimport()はモジュールの読み込みを非同期で行います。つまりPromiseを返します。

import("./util").then(({ increment }) => {
  console.log(increment(3));
  // @log: 4
});

なるほど


> Node.jsでES Moduleを使う
> ES Moduleとして動作させたいJavaScriptのファイルをすべて.mjsの拡張子に変更します。

ややこしい
importで使うファイルの拡張子が省略できないことに注意してください。

> "type": "module"
package.jsonにこの記述を追加するとパッケージ全体がES Moduleをサポートします。 

なお"type": "module"の省略時は"type": "commonjs"と指定されたとみなされます。これは今までとおりのNode.jsです。

CommonJSで書かれたJavaScriptを読み込みたくなったときはCommonJSで書かれているファイルをすべて.cjsに変更する必要があります。

ES Moduleにはrequire()がなく、一手間加えて作り出す必要があります。

import { createRequire } from "module";

すべてをES Moduleとして読み込むこの設定は、多くのパッケージがまだ"type": "module"に対応していない現状としては非常に使いづらいです。

TypeScriptでは一般的にES Module方式に則った記法で書きます。

執筆時(2021/01)

ブラウザ用であればES Moduleを、サーバー用であればCommonJSが無難な選択肢になります。

ひとつのファイルから複数exportできる

namedがつよそう

ロジックが変わったこととそれによる修正を強制したいのであればnamed exportを使う方がわかりやすく、そしてエディター、IDEを通して見つけやすくなる利点があります。逆に、公開するパッケージのようにAPIが一貫して明瞭ならばdefault exportも価値があります。


2022/02/20  4:08
シングルプロセス
3700地

https://typescriptbook.jp/reference/single-process-and-callback

02:00 にはじめてる
あと7項目

ブロッキングの逆の概念です。Node.jsはノンブロッキングI/Oを取り扱うことができます。

いままでsetTimeout()は第2引数のミリ秒だけ遅延させてコールバック関数を実行すると説明していましたが、厳密にはミリ秒経過後にメッセージキューに戻すだけで、そのコールバック関数が即座に実行されるわけではありません。

終わった 2022/02/20  4:17
9分 ながら つまり、 400地/分かな
 つまり、1時間 24000地、 2時間で 50000地 一日に文庫本 100ページ読んでることになる


TypeScriptでは型から別の型を導き出す機能があります。既存の型を再度利用して、新たな型を生み出すことを本書では「型の再利用」と呼ぶことにします。

型の再利用とは、変数の再利用のメタファーなのです。

あとご項目 2022/02/20  4:21

TSって 方追加ダケタなくて、インターフェイスとか色々も追加されてるのね

TypeScriptのtypeofは変数から型を抽出する型演算子です。

type Point = typeof point;

ここで説明したのはTypeScriptのtypeof型演算子です。JavaScriptのtypeof演算子と同じ名前ですが、まったく別のものなので注意してください。

めちゃむず

べつの名前にすればいいのに

type PersonKey = keyof Person;

type BookKey = "title" | "price" | "rating";


interfaceとtypeの違い の次が 
    tsconfigの設定項目に関して
なので、この辺飛ばしてそうかも??

> インデックス型にkeyofを用いると、インデックスキーの型が返ります。 キーがstringのインデックス型は、stringではなくstring | numberが返ります。number型のキーアクセスのobj[0]はobj["0"]と同じになるからです。

any型にkeyofを使うとstring | number | symbol型が返ります。

このメモも 42400文字ある既に 2022/02/20  4:25

keyofを使うとそもそも書き写す必要がないため、便利な上に安全なコーディングができます。

ユーティリティ型(utility type)は、型から別の型を導き出してくれる型です

functionが実行時の世界の関数だとしたら、ユーティリティ型は型の世界の関数といったイメージです。 

Requiredは、Tのすべてのプロパティからオプショナルであることを意味する?を取り除くユーティリティ型です。

type RequiredPerson = Required;

Readonlyの効果は再帰的ではない

やっとおわり 
2022/02/20  4:28
2時間はん ながら

明日は
noUnusedParameters
まで
確かにあと2日でおわりそう

2022/02/20 19:31

開始

Partialは、オブジェクト型Tのすべてのプロパティをオプションプロパティにするユーティリティ型です。

PartialをOptions Objectパターンに応用すると、省略可能でありながら見やすい関数を実装できます。

急にながくなった

Partialを使って見た目をよくできます。


}: FindUsersArgs): Promise {

}: FindUsersArgs = {}): Promise {

> RecordはプロパティのキーがKeysであり、プロパティの値がTypeであるオブジェクト型を作るユーティリティ型です。

オブジェクト型
type Person = Record<"firstName" | "middleName" | "lastName", string>;

Pickは、型TからKeysに指定したキーだけを含むオブジェクト型を返すユーティリティ型です。

便利そう

型引数Tにはオブジェクト型を代入します。

type Person = Pick;

このようにすればBookInputDataは少なくともBookとコード上の繋がりができる上に、authorプロパティの型変更を自動で追従してくれるようになります。

Omitは、オブジェクト型TからKeysで指定したプロパティを除いたオブジェクト型を返すユーティリティ型です。

OmitのKeysにTには無いプロパティキーを指定しても、TypeScriptコンパイラーは指摘しません。たとえば、Keysにタイポがあっても検出できないので注意が必要です。



Extractは2つのユニオン型の共通部分を導き出すことにも使えます。


次は Mapped type 
https://typescriptbook.jp/reference/type-reuse/mapped-types

あと20項目 2022/02/20 19:59

入力の形式が決まっているのであればMapped typeの使用を検討できます。

べんりそう

type SystemSupportLanguage = "en" | "fr" | "it" | "es";


type Butterfly = {
  [key in SystemSupportLanguage]: string;

TypeScriptのインデックスアクセス型(indexed access type)は、プロパティの型や配列要素の型を参照する方法を提供します。

type A = { foo: number };
type Foo = A["foo"];

keyof型演算子と組み合わせると、オブジェクトの全プロパティの型がユニオン型で得られます。

> 配列型の要素の型を参照するのにもインデックスアクセス型が使えます。要素の型を参照するには、配列型に[number]をつけます。

めちゃむず

type StringArray = string[];
type T = StringArray[number];

type State = typeof stateList[number];
type State = "open" | "closed"

type Tuple = [string, number];
type T = Tuple[0];


型の安全性とコードの共通化の両立は難しいものです。

型の安全性を重視しようとすると、同じようなコードを量産する必要が出てコードの共通化が達成しづらくなります。

ジェネリクスの発想は実はとてもシンプルで、「型も変数のように扱えるようにする」

function chooseRandomly(v1: T, v2: T): T {

chooseRandomly("勝ち", "負け");

chooseRandomlyのは型変数名の定義です。慣習としてTがよく使われますが、AでもTypeでも構いません。関数の引数の型や戻り値の型として書かれたTは型変数を参照しています。


Arrayは特別に別の記法で型表記をすることもできます。これらについては配列のページに詳細がありますので併せて参照ください。

ジェネリクスの型定義はひとつである必要はなく、複数の型定義を持つことも可能です。

型変数(type variables)は、もうひとつの便利な入れ物です。ただし、入れられるのは「値」ではなく「型」という違いがあります。

この関数を利用するコードは、numberなどTに好きな型を代入することができます:

const value = printAndReturn(123);

TypeScriptでは、型引数にも型推論が行われます。型引数推論(type argument inference)と言われます

変数の123から型変数Tの型はnumber型になることがコンパイラからは推測可能なので、次のコードのように型引数の記述を省略することもできます。

const value = printAndReturn(123);

function func5<かた>(x: かた) {}

型変数名に使えないものは数字ではじまるもの、classなどの予約語です。

単純なジェネリクスで、型変数が2つある場合は、TとUが用いられることがあり、その理由はアルファベット順でTの次がUだからです。この規則にしたがって、3つ目の型変数はVする場合もあります。

複数の型変数がある場合、型変数に意味のある名前をつけることもあります。その場合、TKey、TValueのようにT接頭辞を付けた命名規則がしばしば使われます。ただし、これは「型変数名にはTを用いる」という慣習ほどは一般的でないように思われます。

型変数名を単語にする場合は、大文字始まりのキャメルケースにすることが普通です。

ジェネリクスはそもそも抽象的なものごとを扱うため、具体的な名前が付けられないため、意味を持たないTのほうがいいという考え方があります。

Elementのような型変数名を定義すると、一見するとそれがクラス名のように見えてしまいます。混乱を避けるためにもTのほうがよいという意見があります。

型変数にも同じことが言えて、型変数のスコープが広いものは単語にし、短いジェネリック関数の中でしか使わない型変数は1文字が妥当という考え方があります。

コンパイラは存在しないプロパティへの参照が発生する可能性を検知してコンパイルエラーとしているのです。

function changeBackgroundColor(element: T) {

このextendsキーワードはインターフェースに対しても使います。インターフェースは実装のときはimplementsキーワードを使いますが型引数に使うときはimplementsを使わず同様にextendsを使います。

type MyErrorEvent = {

type MyErrorEvent = {

class Aubergine {

デフォルト型引数は左から順に参照されるため、左にあるジェネリクスが右のジェネリクスを指定することはできません。

2022/02/20 21:20
tsconfig.jsonを設定する
に到達
https://typescriptbook.jp/reference/tsconfig/tsconfig.json-settings

4400もじ 

あと12項目

Node.jsはそれ自身ではTypeScriptをサポートしているわけではないため、TypeScriptの導入をする時はTypeScriptの設定ファイルであるtsconfig.jsonが必要です。


typescriptがグローバルインストールされていればnpx不要

使いたいtargetには使いたい機能がない、でも使いたい。そのような時はlibオプションを指定することで使うことができるようになります。

むずかめんどそうポイント

指定したtargetでは実装されていないライブラリや、必要がないライブラリを除外したいときに使います。

軽くなりそう

>     "target": "es2018",
>     "lib": [
      "es2018",
      "esnext.AsyncIterable",
      "esnext.Array",
      "esnext.Intl",
      "esnext.Symbol"
    ]


あえて古いコードで動かしている、または古いNode.jsを使っているといった事情がなければ最新に近い物を指定することは問題ありません。

Node.js 14.xであれば"target": "es2020"は無難な選択肢です。

またBabelなどの専用のコンパイラやモジュールバンドラに処理を任せたい場合はtargetに"esnext"を指定して、そこからバージョンに合わせたコンパイルを各々にお願いすることになります。

Node.jsのバージョンごとにサポートされているEcmaScriptの機能は node.green で確認することができます。

とくにnpm installしたものであればこれらをパッケージと呼びます。

モジュール読み込みの仕組みが異なっているライブラリの互換性は一般的にはないものと考えてください。そしてこれはフロントエンドとバックエンドでは異なります。

es2015, es2020, esnext
通称esmoduleと呼ばれるモジュール読み込みの解決方法です。

スクラッチから作るということは現在の資産との整合性の都合、しがらみが一切ない状態です。ここから作るならこれだけは満たしておけば型に満ちたプログラミングができるという紹介です。

strictはstrict系のコンパイラオプションを一括で有効化するコンパイラオプションです。
個々の設定が優先されます。

戻り値の型注釈を必須にしたい場合は、noImplicitReturnsを有効にしてください。

再開 2022/02/21  0:36
あと9項目

さすがに個々の設定は短いかな?

とりあえず、できるものならtrueにするのがよさそう

TypeScriptの関数には引数の双変性(parameter bivariance)という性質があります

TypeScriptの関数型は、引数の反変性と引数の共変性の両特性を持っています。この両特性は一言で、引数の双変性と言います。

引数の共変性を許さないstrictFunctionTypes

strictFunctionTypesのチェックが働くのは関数型だけです。メソッド型には働きません。

プロパティがオプションの場合も警告が出ません。

まぁ、すいしょうなのは極力trueにするよね

2022/02/21  0:48
あと4つ

alwaysStrict
'use strict'を各ファイルの先頭に付加します。

便利

終わり 2022/02/21  1:05
機能ほど、長い項目なくて楽だった

明日は25項目で最後まで。

2022/02/21 22:57

やってこ

https://typescriptbook.jp/reference/tsconfig/exactoptionalpropertytypes
から

型定義ファイルを同梱することにより補完やコードチェックとして利用することができます。

ヘッダーファイルだ

tsc -d
でつくれる

    JavaScriptで書かれたパッケージだが、 DefinitelyTypedに登録されている

TypeSearchからパッケージ名を検索しインストールを行います

npm install @types/express --save-dev # 型定義ファイルのインストール

なるほど @types/ の意味がやっとわかったぞ

型定義ファイルを一緒に出力しましょう。そのためにはtsconfig.jsonにあるdeclarationの項目をtrueに変更します。


"sourceMap": true,

> 確かにフロントエンドを動的にしたいのであればほぼ避けて通れないJavaScriptと、バックエンドでも使えるようになったJavaScriptで同じコードを使いまわせれば保守の観点でも異なる言語を触る必要がなくなり、統一言語としての価値が大いにあります。

むふう

  "extends": "./tsconfig.base.json",

このようなtsconfig.xxx.jsonができていれば、あとは次のようにファイル指定してコンパイルをするだけです。

tsc -p tsconfig.cjs.json

module bundlerは容量削減のための涙ぐましい努力を続けています

Tree Shakingとは使われていない関数、クラスを最終的なjsファイルに含めない機能のことです


ここで言及している副作用とは以下が挙げられます。

    exportするだけで効果がある
    プロトタイプ汚染のような、既存のものに対して影響を及ぼす

  "sideEffects": ["./xxx.js", "./yyy.js"],


Generatorを使用した関数はアロー関数での表記ではなく、必ずfunction*() {}と書く必要があります。次は可能なGeneratorの記述方法です。

中級者でみた

現在でも大量のデータを取得したいときに一度ではなく、小出しに取得したいときにGeneratorは使い道があります。


プロパティへのインターセプター(参照・代入・監視などの意味)としGetter/Setterがあります。

あと 12項目 2022/02/21 23:56

自分たちでこのパッケージに手を加えることは容易ではないため (できなくはありません) 。制作者にプルリクエストを出してバグフィックスが行われるまで開発を止めるというのも現実的ではありません


浅いコピーの実装は昨今のJSでは大変楽になっており、次のコードで完成です。

const shallowCopied: object = { ...sample };

スプレッド構文は配列をはじめとするコレクションに対しても使うことができます。

const merged = { ...obj1, ...obj2 };

const merged = {
  ...obj1,
  ...obj2,
  ...obj3,
  // ...
};

あと10項目 2022/02/22  0:08

2つ目の方法はlodashを用いるものです。lodashはさまざまな便利関数を提供するライブラリで、その中のひとつにpickというオブジェクトのサブセットを得るための関数があります。

npm install -D @types/lodash

型情報もゲットしよう

関数やメソッドでオブジェクトひとつを引数として受け、戻り値もオブジェクトひとつとする RORO という考え方があります。RORO は Receive an Object, Return an Object の略です。この考えは JavaScript ならびに TypeScript では大きな恩恵をもたらします。

TypeScriptでは値と型に同名を与えてその両方を区別なく使うことができるテクニックがあります。これをコンパニオンオブジェクトと呼びます。
これは、クラスを作るほどでもなけどそれっぽいファクトリーメソッドとオブジェクトが欲しいときに重宝します。

type Account = typeof account;

> } as const;
type Account = typeof account;

リテラル型になる

>   plan: "Standard" as "Free" | "Standard" | "Premium",

この const の 型への変換べんりだな typeof

keyofはオブジェクトの型に使うとそのオブジェクトのキーをユニオン型にして返します。上記のTypeOfLanguage型があれば

type Language = keyof TypeOfLanguage;

type Language = keyof typeof conf;

keyofは値ではなく (オブジェクトの) 型に対して使用できる


type ConfirmationMessage = typeof conf[Language];

type Currency = typeof currencies[number];

numberをいれると 0とか 1とかの代わりのユニオン型になるらしい

() 即時実行関数の一部 (IIFE: immediately invoked function expression) js
定義されるとすぐ実行される即時実行関数式(IIFE; Immediately Invoked Function Expression)の一部に用いられる書き方です。

- 修飾子の削除 ts

readonlyや?などの修飾子を削除します。

type MyRequired = {
  [k in keyof T]-?: T[k];
};
type Writable = {
  -readonly [k in keyof T]: T[k];

/** JSDoc
慣習的にJSDocなどのドキュメンテーションコメントの開始を表す記号です。これはJavaScriptやTypeScriptの構文ではなく、複数行コメントを用いたドキュメンテーションに慣習的に用いられるものです。


>> ビット右シフト演算子 (right shift) js

左の値のビットを右の値の数だけ右にずらします。

const a = 8;

00001000
const b = 3;
console.log(a >> b);

00000001

?? Null合体 (nullish coalescing operator) js

左の値がnullまたはundefinedのときに右の値を返します。そうでない場合は左の値を返します。

console.log(undefined ?? 1);

1
console.log(2 ?? 1);

2

const user2 = { name: "kaori" };
user2.name ??= "taro";
console.log(user2.name);

kaori

https://typescriptbook.jp/symbols-and-keywords


@ デコレーター (decorator) ts
デコレーターはクラスやクラスメンバーに注釈を追加するもので、デコレーターを使うのに用いられる記号です。

そいうのもあるのね

2022/02/22  0:46
もうすぐで二時間かな?

インデックス型(index signature)の開始に用いられる記号です。

type StringKeysAndStringValues = {
  [key: string]: string;
};

また、慣習的に使わない変数の受け取り先に使われることがあります。たとえば、2つの引数を受け取るコールバック関数で、第2引数だけを使う場合、第1引数をアンダースコアにする書き方をするコードが中にはあります。

[1, 2, 3].map((_, index) => {
  //  _ は 1, 2, 3のような要素値。それを使わないという意味で _ にしている


if文やfor文などの構文を伴わないブロック文は、単に変数のスコープを分けることを目的にしていることがあります。

{
  const value = 1;
}

~~ Double Tilde js
ビット否定演算子を2つ重ねたもので、小数点以下を消し去る計算をするイディオムです。JavaScriptにこういう演算子があるわけではなく慣習的なものです。double tildeの計算結果は、正の数についてはMath.floorと同じに、負の数はMath.ceilと同じになります。


typeof typeof演算子 (typeof) js

与えられた値の型を表す文字列を返します。

console.log(typeof 123);

"number"

typeof typeof型演算子 (typeof) ts
変数から型を抽出する演算子です。

なぜ「これはTSの方のtypeof」とか見分けられるのか
 JSのは変数に使えないのかな?


void void演算子 (void) js

戻り値をundefinedにします。

console.log(void 123);


TypeScript Playground
https://www.typescriptlang.org/play

    エディターのコードを文字列圧縮ライブラリで圧縮して文字列をURLに設定する
    URLを共有する
    共有されたURLが開かれる時に圧縮された文字列をデコードしてエディターに展開する

こんなにちっちゃく圧縮できるんだね

おわった! 2022/02/22  0:54