Open12
TypeScriptでインポートしたJSONにnarrowingした型をつけたい
モチベーション
これを
index.ts
import { createRule } from '@markuplint/ml-core';
export default createRule({
meta: {
"category": "validation"
},
// 略
});
こうしたかった
meta.json
{
"category": "validation"
}
index.ts
import { createRule } from '@markuplint/ml-core';
import meta from './meta.json';
export default createRule({
meta: meta,
// 略
});
なぜかというと、ビルドせずともcategoryの情報だけの他のファイルから読み取りたいから。
問題
TypeScriptでJSONのインポート自体は問題なくできる。
しかし、型付けが不完全
{
"category": "validation"
}
をインポートした場合、型は
{
"category": string
}
になる。
しかし、渡す先の型は
readonly meta?: {
readonly category?: 'validation' | 'style' | 'naming-convention' | 'a11y' | 'maintainability';
};
こうしていたため、stringでは渡せない。
択
- JSONを絞り込む
- 渡す先の引数の型を
string
に広げてしまう。 - type assertionする
- ts-ignoreする
JSONの型を絞り込めればそれがいい。
TS内でいえば、 as const
すればnarrowingできるので、そういうことがしたい
const meta = {
category: 'validation',
} as const
JSONの型、絞り込めない
らしい。
issue立ってるけど実装されてない
試したこと
どうにもうまく適用されなかった
.d.ts
.d.json.ts
いや、他のリポジトリで .d.json.ts
を試したら正しく型付けが上書きされた
単にどこかの設定が悪い説あるな
(問題の切り分け、大事だなあ~)
あ、他のディレクトリに置いちゃったからだめなのであって、同じディレクトリに置く必要あるのか
同じディレクトリに置いたら解決した
けど meta.default
で参照しなきゃいけなくなったっぽい?
.defaultつけないと書いてるときはエラーになるけど、
ビルドしたら.defaultつけてないのが正しいから普通にバグか
そして全ファイルに置く必要あるのもめんどいな~
でも仕方ないのか
そもそも .default
のバグがある以上、ここでは使えないかも
なので大人しく as
でアサーションするか…