SlideShare a Scribd company logo
1 of 52
Download to read offline
TypeScript の型定義を
PRする技術
ypresto / Yuya Tanaka
kansai.ts #2
Picture: Ron Clausen (CC-BY-SA 4.0)
with trimming & color filter applied by ypresto
注:ちゃんとTSのサイトと同じシアトルの画像です
@yuya_presto
@ypresto
codeTakt: 学校教育系エンジニア
フルリモート / 保育士資格
Yuya Tanaka
bit.ly/ypresto-d-ts
業務連絡:ロクにナレッジシェアもせずすみませんでした・・
あ、でもこのQiita記事書いてた
(削除超過分はyarn.lock)
bit.ly/ypresto-d-ts
At least 12 PRs!
bit.ly/ypresto-d-ts
型定義を書く
bit.ly/ypresto-d-ts
控えめが過ぎる
oO(ライブラリのimportにだけ有効な noImplicitAny 誰か作ってください!!
初級編
中級編
▼
上級編
PRできる型を作り上げるまで
https://github.com/fnando/i18n-js
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/83e5c8c944d18bf5ea542428
a75dd79934be5333/types/i18n-js
(短縮→ http://bit.ly/ypresto-dt-i18n-js )
↑作ってPRした
型情報を収集する(人力)
1. ドキュメントから
2. サンプルコードから
3. 本体のコードから
1. ドキュメントから
2. サンプルコードから
2. サンプルコードから
ドキュメントから
切り出して型のテストに!
3. 本体のコードから
3. 本体のコードから
正確だけど
ぶっちゃけ大変
確認時にGood
あとドキュメントされてない
パラメータも見つかる?
型定義ならではの
お作法
1. export =
2. namespace
3. 型のexport
これじゃダメなん?
▶export defaultを並べて書くと壊れるライブラリが多い
この書き方はES Modulesのライブラリ専用
(esModuleInteropがオフのとき)
実行時にTypeError
「dayjs_1.default is undefined」
例:export =で書かれているdayjsの
型定義をexport defaultにしてみる
↑文言は適当
1. export =
TS / ES Modules CommonJS
export default Foo module.exports.default = ...
import Foo from 'foo' var Foo = require('foo').default
export = Foo // TS専用 module.exports = ...
import * as Foo from 'foo'
import Foo = require('foo') // TS
var Foo = require('foo')
esModuleInteropがONの場合、よしなに対応
import Foo from 'foo' var foo = require('foo')
var Foo = fooがES Modules
? foo.default : foo
1. export =
TS / ES Modules CommonJS
export default Foo module.exports.default = ...
import Foo from 'foo' var Foo = require('foo').default
export = Foo // TS専用 module.exports = ...
import * as Foo from 'foo'
import Foo = require('foo') // TS
var Foo = require('foo')
esModuleInteropがONの場合、よしなに対応
import Foo from 'foo' var foo = require('foo')
var Foo = fooがES Modules
? foo.default : foo
現代、多くはこっちのはず
(babelしてる場合とか)
1. export =
TS / ES Modules CommonJS
export default Foo module.exports.default = ...
import Foo from 'foo' var Foo = require('foo').default
export = Foo // TS専用 module.exports = ...
import * as Foo from 'foo'
import Foo = require('foo') // TS
var Foo = require('foo')
esModuleInteropがONの場合、よしなに対応
import Foo from 'foo' var foo = require('foo')
var Foo = fooがES Modules
? foo.default : foo
NOTE: I18n.defaultLocale = 'ja' は
TS専用requireで書かないとできない
(ES Modulesはreadonly)
1. export =
TS / ES Modules CommonJS
export default Foo module.exports.default = ...
import Foo from 'foo' var Foo = require('foo').default
export = Foo // TS専用 module.exports = ...
import * as Foo from 'foo'
import Foo = require('foo') // TS
var Foo = require('foo')
esModuleInteropがONの場合、よしなに対応
import Foo from 'foo' var foo = require('foo')
var Foo = fooがES Modules
? foo.default : foo
esModuleInteropは
使い手でONとは限らない
1. export =
2. namespace
3. 型のexport
2. namespace
var I18n = {} // POJOやfunctionを用意し
modules.exports = I18n // まるっとexport!
// プロパティ刺して
dayjs関数オブジェクトに .locale() も生えてる
そう、namespaceならね
1. export =
2. namespace
3. 型のexport
お前は
誰だ?
2.5. export as namespace
ブラウザ直loadでも使える
UMD形式の場合は書く!
例: window.$ とか
i18n-jsのコード
1. namespace
2. export =
3. 型のexport
3. 型のexport
ES Modulesでtop-level(かdeclare module直下)に型を書く場合、
複雑な引数や返り値など、必要な型にはexportを!
NOTE: exportしたnamespaceの中の型は勝手に見える模様
その他のヒント
● 本体にPRするときは package.json に "types": "index.d.ts" を追加
● DefinitelyTypedにPRするときはContribution guideを読む
● 複数ファイルのライブラリは foobar.js に対応して foobar.d.ts を追加
▶ import ... from 'hoge/foobar' したときに読んでくれる
● モチベを保つには:自分のプロジェクトの
declare moduleの中で書き始めて、後でPRにする
FAQ(?)
Q. 新しいライブラリに
型定義をつけて
配りたいのですが?
A. 令和時代のライブラリは
最初からTypeScriptで
書きますよね??
まとめ
型定義を書くには
1. ドキュメントから型情報を
2. サンプルコードから型のテストを
3. 本体のコードで照合を
型定義のお作法
1. exportに必要ならnamespaceを使う
2. export = を書き分ける
2.5. UMDは export as namespace
3. 型もexportしてあげる
型とはドキュメントで、
型とはテストだ!!
書いてないところは基本anyなので、他のoptionでエラーになりにくい(多分
実際はへタレだったので strictNullChecksとnoImplicitThisだけからでした・・
余談:strictしませんか?
1. export =
TS / ES Modules CommonJS
export default Foo module.exports.default = ...
import Foo from 'foo' var Foo = require('foo').default
export Foo module.exports.Foo = ...
import { Foo } from 'foo' var Foo = require('foo').Foo
export = Foo // TS専用 module.exports = ...
import * as Foo from 'foo' var Foo = require('foo')
esModuleInteropがONの場合、よしなに対応
import Foo from 'foo' var foo = require('foo')
var Foo = fooがES Modules
? foo.default : foo
1. export =
TS / ES Modules CommonJS
export default Foo module.exports.default = ...
import Foo from 'foo' var Foo = require('foo').default
export Foo module.exports.Foo = ...
import { Foo } from 'foo' var Foo = require('foo').Foo
export = Foo // TS専用 module.exports = ...
import * as Foo from 'foo' var Foo = require('foo')
esModuleInteropがONの場合、よしなに対応
import Foo from 'foo' var foo = require('foo')
var Foo = fooがES Modules
? foo.default : foo
import * as React from 'react'
▼
import React from 'react'
import React, { useState } from 'react'
1. export =
DefinitelyTypedより lodash/keyBy.d.ts
DefinitelyTypedより lodash-es/keyBy.d.ts

More Related Content

Similar to TypeScriptの型定義をPRする技術 (ypresto / kansai.ts #2)

doctest を書こう @ pycon kansai
doctest を書こう @ pycon kansaidoctest を書こう @ pycon kansai
doctest を書こう @ pycon kansaiYosukeHojo
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用についてmichiosuzuki
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用についてmichiosuzuki
 
とあるFlashの自動生成
とあるFlashの自動生成とあるFlashの自動生成
とあるFlashの自動生成Akineko Shimizu
 
拡張機能の歴史と標準化
拡張機能の歴史と標準化拡張機能の歴史と標準化
拡張機能の歴史と標準化Ryouyu Oonuma
 

Similar to TypeScriptの型定義をPRする技術 (ypresto / kansai.ts #2) (6)

doctest を書こう @ pycon kansai
doctest を書こう @ pycon kansaidoctest を書こう @ pycon kansai
doctest を書こう @ pycon kansai
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について
 
鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について鈴木:Net commonsでの中国語使用について
鈴木:Net commonsでの中国語使用について
 
とあるFlashの自動生成
とあるFlashの自動生成とあるFlashの自動生成
とあるFlashの自動生成
 
Titanium実装最初の一歩.
Titanium実装最初の一歩. Titanium実装最初の一歩.
Titanium実装最初の一歩.
 
拡張機能の歴史と標準化
拡張機能の歴史と標準化拡張機能の歴史と標準化
拡張機能の歴史と標準化
 

TypeScriptの型定義をPRする技術 (ypresto / kansai.ts #2)