0
0

More than 1 year has passed since last update.

【覚書】JSDoc + ts-check で as any as を実現する

Last updated at Posted at 2021-10-10

//@ts-check で JS を書いていて、
as any as とか as unknown as とか
(window as any).hoge とかみたいな書き方がしたくなったので調べた。

ふつうはこうなる

//@ts-check

document.createElement("div").innerText = 12345;
// -> Type 'number' is not assignable to type 'string'. ts(2322)

TypeScript ならこれでゴリ押せる

document.createElement("div").innerText = 12345 as any as string;
document.createElement("div").innerText = 12345 as unknown as string;

でも JSDoc では当然このような書き方はできない・・・

ts-expect-error は代案にならない

TypeScript では as any as を使用することで、以下のように変数の型をそのまま変更できるが

const value = 12345 as any as string;

type X = typeof value;
// -> type X = string

@ts-expect-error はエラーを無視するだけなので、変数の型は変化しない。

const value = 12345;
//-> const value: 12345

//@ts-expect-error
document.createElement("div").innerText = value;

だから @ts-expect-erroras any as と同じように使うことはできない。

JSDoc の @type だとエラる

//@ts-check

/** @type {string} */
const value = 12345;
// -> Type 'number' is not assignable to type 'string'. ts(2322)

document.createElement("div").innerText = value;

これが JSDoc の正解

といっても、あまりスマートじゃないし裏技じみてるが。

//@ts-check

/**
 * @template T
 * @param {(type: T) => any} def
 * @param {unknown} from
 * @returns {T}
 */
const resolveTypeAs = (def, from) =>
  //@ts-expect-error
  from;

const value = resolveTypeAs(
  /** @param {string} _ */ (_) => _,
  12345
);
// -> const value: string

document.createElement("div").innerText = value;

resolveTypeAs という、型を強制的に書き換える関数を作る。
第一引数で @param に無名関数の引数として T となる型を渡す形にした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0