Set data Type in Vue data object with Typescript

I'm currently using Vue.js with Typescript in a webpack project.

As indicated in the Recommended Configuration in my tsconfig.json I have:

"strict": true,

Inside one of my component i have:

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); }); }, });

but when I try to compile i get:

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

Cause I believe players: [] has never[] type.

My question is: how can I infer type Vue data object properties??

6 Answers

To add to Joshua's answer, you may want to declare the type of players inline so your code doesn't get too verbose as your data gets larger.

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

another option:

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

This should work:

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

Your data method has an undeclared return value.

If you supply one, TypeScript will know what to expect with players.

You just need to expand the data() { line.

e.g.:

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

needs to become:

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

Tada! players is now of type Array of any.

4

I found another method that is more close to the typical syntax, while keeping the code short.

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

Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead.

It will look like this:

players: [] as Player[]
2

In case anyone comes across this in the future, here is the answer that solved my problem. It is a little more "wordy", but it does the type inference properly everywhere within the Vue.extend() component definition:

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); }); }, });

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like