使用Typescript在Vue数据对象中设置数据类型

Pla*_*tic 13 typescript vue.js vuejs2

我目前正在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);
       });
    },
 });
Run Code Online (Sandbox Code Playgroud)

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

 error TS2345: Argument of type 'Player' is not assignable to parameter of type 'never'.
Run Code Online (Sandbox Code Playgroud)

因为我相信players: []never[]类型.

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

Mic*_*son 25

要添加到Joshua的答案中,您可能希望声明内联类型的玩家,这样您的代码就不会因为数据变大而变得过于冗长.

data() {
  return {
    players: [] as Player[]
  };
},
Run Code Online (Sandbox Code Playgroud)


Ore*_*444 15

这应该有效:

declare interface Player {
  cod: string,
  param: string
}

declare interface BaseComponentData {
  players: Player[]
}

export default Vue.extend({
  name: 'basecomponent',
  data(): BaseComponentData {
    return {
      players: []
    };
  },
})
Run Code Online (Sandbox Code Playgroud)


Ahm*_*mad 12

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

data() {
  return new class {
    players: Player[] = []
  }();
},
Run Code Online (Sandbox Code Playgroud)


Jos*_*sen 11

您的data方法有一个未声明的返回值。

如果您提供一个,TypeScript 将知道对players.

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

例如:

data() {
  return {
    players: []
  };
},
Run Code Online (Sandbox Code Playgroud)

需要变成:

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

多田!玩家现在是任何类型的数组。

  • 我认为你建议的代码第二行的第一个单词应该是“players”,而不是“people”。 (2认同)

小智 8

禁止使用“<>”语法进行类型断言。请改用“as”语法。

它看起来像这样:

players: [] as Player[]
Run Code Online (Sandbox Code Playgroud)

  • @nomadoda 这不是禁止的,我认为 Илья Карев 指的是 TSlint 警告您使用 `&lt;T&gt;` 进行类型转换,您应该更喜欢 `myVar as T` 语法的原因是由于缺乏 JSX 支持。您可以在 TypeScript 文档中阅读 https://www.typescriptlang.org/docs/handbook/jsx.html (3认同)

th3*_*guy 5

如果将来有人遇到这个问题,这里是解决我的问题的答案。它有点“冗长”,但它在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);
       });
    },
 });
Run Code Online (Sandbox Code Playgroud)