💭

Vue(Nuxt)の ref で .value を書かなかった時怒ってほしい

に公開

Vueの ref で .value をつけ忘れたらどうなるか
簡単に怖いことが起きる

  const test = ref(false);

  if (test) { // valueついてないよって言って欲しい
    console.log('通っちゃう')
  }

testはオブジェクトなので ts的にはifに渡しても型の問題にはならない
今は削除されたRefの変数に.valueつけなくても参照できるようにしようぜ!という
賛否しかなかったReactive Transfer的にはOKな書き方

まぁ実際には実装時に変な動きするのですぐわかるだろ?という話だけど
昨今AIにコード生成させているので油断ならない

とはいえvue独自の仕様なのでtsにもESLintには当然このルールはない
作るしかない

import { ESLintUtils } from '@typescript-eslint/utils';

module.exports = ESLintUtils.RuleCreator(() => '')({
  name: 'require-ref-value',
  meta: {
    type: 'problem',
    docs: {
      description: 'Disallow using Ref directly in conditionals, require .value',
      recommended: 'warn',
    },
    messages: {
      requireValue: 'Do not use Ref directly in condition. Use ".value".',
    },
    schema: [],
  },
  defaultOptions: [],
  create(context) {
    const service = context.parserServices;
    if (!service?.program || !service?.esTreeNodeToTSNodeMap) {
      // 型情報が取れない場合はこのルールを無効化
      return {};
    }

    const checker = service.program.getTypeChecker();

    return {
      IfStatement(node) {
        if (node.test.type !== 'Identifier') return;

        const tsNode = service.esTreeNodeToTSNodeMap.get(node.test);
        const type = checker.getTypeAtLocation(tsNode);

        // Ref<T> の型判定
        if (type.symbol?.name === 'Ref') {
          context.report({
            node: node.test,
            messageId: 'requireValue',
          });
        }
      },
    };
  },
});

怒ってくれた

でも windsurfは優秀だった

ちなみに代入はちゃんと型定義しておけば怒られる

常時動かしておくほどのルールでもなかった

Discussion