将数据类型设置为使用TypeScript的VUE数据对象



我当前正在使用WebPack项目中的Typescript的Vue.js。

如我的tsconfig.json中建议的配置所示:

"strict": true,

在我的一个组件之一中,我有:

declare interface Player {
    cod: string,
    param: string
  }
export default Vue.extend({
    name: 'basecomponent',
    data() {
      return {
        players: []
      };
    },
    created() 
      let self = this
      axios.get('fetch-data')
        .then((response) => {
          let res: Players[] = response.data;
          for(let i = 0; i < res.length; i++){
              self.players.push(res[i]);
          }
        })
        .catch((error: string) => {
          console.log(error);
       });
    },
 });

但是当我尝试编译时,我得到了:

 error TS2345: Argument of type 'Player' is not assignable to parameter of type 'never'.

因为我相信 players: []具有never[]类型。

我的问题是:如何推断类型VUE数据对象属性??

要添加到约书亚的答案中,您可能需要声明播放器的类型,因此随着数据的较大,您的代码不会太冗长。

data() {
  return {
    players: [] as Player[]
  };
},

另一个选项:

data() {
  return {
    players: new Array<Player>()
  };
},

这应该有效:

declare interface Player {
  cod: string,
  param: string
}
declare interface BaseComponentData {
  players: Player[]
}
export default Vue.extend({
  name: 'basecomponent',
  data(): BaseComponentData {
    return {
      players: []
    };
  },
})

您的data方法具有未确定的返回值。

如果您提供一个,那么Typescript将知道players的期望。

您只需要扩展data() {行。

例如:

data() {
  return {
    players: []
  };
},

需要成为:

data() : {
  players: Array<any>, // if possible, replace `any` with something more specific
} {
  return {
    players: []
  };
},

tada!players现在是anyArray类型。

我找到了另一种更接近典型语法的方法,同时保持代码短。

data() {
  return new class {
    players: Player[] = []
  }();
},

禁止使用'&lt;>'语法键入断言。代替使用" AS"语法。

看起来像这样:

players: [] as Player[]

以防将来有人遇到这个问题,这是解决我的问题的答案。它有点" wordy",但它在Vue.extend()组件中的任何地方都适当地进行推理:

interface Player {
  cod: string,
  param: string
}
// Any properties that are set in the `data()` return object should go here.
interface Data {
  players: Player[];
}
// Any methods that are set in the "methods()" should go here.
interface Methods {}
// Any properties that are set in the "computed()" should go here.
interface Computed {}
// Any component props should go here.
interface Props {}
export default Vue.extend<Data, Methods, Computed, Props>({
    name: 'basecomponent',
    data() {
      return {
        players: []
      };
    },
    // You probably will want to change this to the "mounted()" component lifecycle, as there are weird things that happen when you change the data within a "created()" lifecycle.
    created() {
      // This is not necessary.
      // let self = this
      // If you type the Axios.get() method like this, then the .data property is automatically typed.
      axios.get<Players[]>('fetch-data')
        .then(({ data }) => {
          // This is not necessary.
          // let res: Players[] = response.data;
          // for(let i = 0; i < data.length; i++){
          //     self.players.push(data[i]);
          // }
          this.players = data;
        })
        .catch((error: string) => {
          console.log(error);
       });
    },
 });

不诉诸于描述整个data结构,一种更可行的方法可能是首先将players定义为具有显式类型的变量:

export default Vue.extend({
    name: 'basecomponent',
    data() {
      const players: Player[] = [];
      return {
        players: players
      };
    },
...

这也适用于其他复杂类型,而不仅仅是对数组。虽然我还没有找到如何告诉Volar不要通过初始化器值缩小联合类型的范围-_-

最新更新