TypeScriptでask-sdkの型を利用する
この記事はAlexa Skills Kit SDK Advent Calendar 2018などの12日目が空いているので書いた記事です。 Serverless FrameworkにもTypeScriptでAlexaスキ […]
目次
この記事はAlexa Skills Kit SDK Advent Calendar 2018などの12日目が空いているので書いた記事です。
Serverless FrameworkにもTypeScriptでAlexaスキルを提供するテンプレートが用意されました。また入力されるオブジェクトと、返されるべきオブジェクトがほぼ決まっているものになりますので、AlexaのバックエンドにTypeScriptは非常に有用です。
型定義をどこから手に入れるか
実際に作成する場合、型定義をインポートする必要があります。自前で定義することもできますが、コアチームが用意しているものを使う方が確実でしょう。
型ファイルはask-sdk-model
にまとめられています。GitHubにも公開されていますが、名前が違うので要注意です。
$ npm init -y
$ npm install -D ask-sdk-model
型が使えるかを確認する
では実際に使ってみましょう。試すだけなので、Jest + TypeScriptで引数チェックがちゃんとできているかだけ確認してみましょう。
事前準備
テストツール系をセットアップします。
$ npm i -D jest ts-jest @types/jest typescript
$ ./node_modules/.bin/tsc --init
$ vim package.json
...
"scripts": {
"build": "tsc",
"test": "jest",
"test:watch": "jest --watch"
},
"jest": {
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"globals": {
"ts-jest": {
"tsConfigFile": "tsconfig.json"
}
},
"testMatch": [
"**/__tests__/*.+(ts|tsx|js)"
]
}
}
サンプルコードとテストを書く
続いてテストコードとテスト対象を準備します。型が使われていることを確認するため、わざと異なる型の引数を与えるようにします。
$ vim index.ts
import { interfaces } from 'ask-sdk-model';
import ChargeAmazonPayRequest = interfaces.amazonpay.request.ChargeAmazonPayRequest
export const helloWorld = (obj: ChargeAmazonPayRequest): string => {
console.log(obj)
return `Hello`
}
$ mkdir __tests__
$ vim __tests__/index.test.ts
import { helloWorld } from '../index';
test('basic', () => {
expect(helloWorld('hello')).toBe('Hello');
});
テストを実行する
実行してみましょう。ChargeAmazonPayRequest
のオブジェクトがくるべきところに文字列を入れているので、うまく行けばエラーになるはずです。
$ npm test
FAIL __tests__/index.test.ts
● Test suite failed to run
TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
__tests__/index.test.ts:4:21 - error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'ChargeAmazonPayRequest'.
4 expect(helloWorld('hello')).toBe('Hello');
~~~~~~~
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 1.832s, estimated 2s
Ran all test suites.
error Command failed with exit code 1.
型エラーが出ました。次は指定通りの値にしてみましょう。
$ vim __tests__/index.test.ts
import { helloWorld } from '../libs/index';
test('basic', () => {
expect(helloWorld({
'@type': 'ChargeAmazonPayRequest',
'@version': '2',
'sellerId': 'AEMGQXXXKD154',
'billingAgreementId': 'string',
'paymentAction': 'AuthorizeAndCapture',
'authorizeAttributes': {
'@type': 'AuthorizeAttributes',
'@version': '2',
'authorizationReferenceId': 'sdfwr3423fsxfsrq43',
'authorizationAmount': {
'@type': 'Price',
'@version': '2',
'amount': '1.01',
'currencyCode': 'USD'
},
'transactionTimeout': 0,
'sellerAuthorizationNote': 'Test Seller Authorization Note'
},
'sellerOrderAttributes': {
'@type': 'SellerOrderAttributes',
'@version': '2',
'sellerOrderId': 'ABC-000-123234',
'storeName': 'Test Store Name',
'customInformation': 'Test custom information',
'sellerNote': 'Test seller note'
}
})).toBe('Hello');
});
今度はテストが通ります。
$ npm test
PASS __tests__/index.test.ts
✓ basic (4ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.181s
Ran all test suites.
✨ Done in 3.17s.
終わりに
GitHubのソースを見ると、大体の値は型定義がされています。SDK自身が使ってるのでそうじゃないと困るやつですが。
うまく使って、スキル開発速度をあげていきたいですね。