如何对发送到 Vue 组件的数据进行类型检查?

How to type-check the data sent to a Vue component?

子classed Vue 组件可以像这样启动:

let app = new MyApp({    
  el: '#app',    
  data: {    
    message: 'Hello Vue!',    
    seconds: 0    
  },    
  created() {    
    setInterval(() => {    
      this.econds = 'asd';    
    }, 1000);    
  }    
});    

问题是,Flow 和 TypeScript 都不会注意到第 this.econds = 'asd'; 行的拼写错误或错误类型。有办法解决这个问题吗?也许使用基于 class 的组件库?但是编译是必需的构建步骤吗?

我认为您应该为此正确配置 IDE。

我正在使用 VSCode 和 VSCode 扩展 Vetur https://github.com/vuejs/vetur

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
    name: 'Home',
    data: function() {
        return {
            message: 'Hello Vue!',
            seconds: 0,
        };
    },
    created() {
        setInterval(() => {
            this.econds = 'asd';
        }, 1000);
    },
});
</script>

结合 <script lang="ts"> Vetur 会告诉您 this.econds 这不存在并显示消息:

Property 'econds' does not exist on type 'CombinedVueInstance<Vue, { message: string; seconds: number; }, unknown, unknown, Readonly<Record<never, any>>>'. Did you mean 'seconds'?Vetur(2551)

不需要编译步骤,它是即时的。

这是你需要的吗?

因此,如果您使用 Typescript,则可以使用基于 class 的组件在变量中定义类型。但是这种类型检查只发生在转译步骤中。转译器仍然会生成 Javascript 文件,不会对变量进行类型检查。

另一种方法是使用 typeof(variable) === "number" 手动进行类型检查。该表达式将 return 为真或为假,具体取决于 variable.

的值

方法一

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'

@Component({
    name: 'Home',
})
export default class extends Vue {
    message: string = "Hello, Vue";
    seconds: number = 0;

    created() {
        setInterval(() => {
            this.seconds = 'asd'; // The transpiler will show an error.
        }, 1000);
    },
}
</script>

方法二

<script>
import Vue from 'vue';

export default Vue.extend({
    name: 'Home',
    data: function() {
        return {
            message: 'Hello Vue!',
            seconds: 0,
        };
    },
    created() {
        setInterval(() => {
            let variable = 'asd'
            if (typeof(variable) === "number")
               this.seconds = variable;
        }, 1000);
    },
});
</script>