ktsn / vue-template-loader

Vue.js 2.0 template loader for webpack
MIT License
266 stars 26 forks source link

Type definition can't work with class that derived from Vue #8

Closed fallenleavesguy closed 7 years ago

fallenleavesguy commented 7 years ago
interface WithRender {
    (options: Vue.ComponentOptions<Vue>): Vue.ComponentOptions<Vue>
    (component: typeof Vue): typeof Vue
 }

This signature can't work with class that derived from Vue if subclass have custom property or method

fallenleavesguy commented 7 years ago

e.g.

@withRender
@Component({
})
class AnyComponent extend Vue {
  placeholder: string;
}

It should cause an compile time error:

severity: 'Error'
message: 'Unable to resolve signature of class decorator when called as an expression.
  Type 'typeof Vue' is not assignable to type 'typeof AnyComponent'.
    Type 'Vue' is not assignable to type 'AnyComponent'.
      Property 'placeholder' is missing in type 'Vue'.'
ktsn commented 7 years ago

Ah, maybe we need to modify it to use generics.

interface WithRender {
    <V extends Vue>(options: Vue.ComponentOptions<V>): Vue.ComponentOptions<V>
    <V extends typeof Vue>(component: V): V
 }

Sorry, I cannot check whether this passes type checking now. I'll invest that later if it still does not work.

fallenleavesguy commented 7 years ago

Great. it work. I wrote an interface which didn't use "typeof Vue":

interface WithRender {
        <V extends Vue>(options: Vue.ComponentOptions<V>): Vue.ComponentOptions<V>
        <V extends Vue>(component: V): V
}

Why we should use typeof Vue? Isn't there a Vue namespace?

ktsn commented 7 years ago

Vue is an instance. i.e. const vm: Vue = new Vue() typeof Vue is a constructor. i.e. const Ctor: typeof Vue = Vue

fallenleavesguy commented 7 years ago

@ktsn Thank you very much.

Excuse me.

I want to provide a simple example about typescript here:

class Vue {

}
// instance
const vm: Vue = new Vue();

// constructor
type Ctor = typeof Vue;

// copy the Vue constructor.
// we can use Vue2 the same as Vue
const Vue2: Ctor = Vue;

const vm2 = new Vue2();

console.log(vm2 instanceof Vue); // true

compile to:

var Vue = (function () {
    function Vue() {
    }
    return Vue;
}());
// instance
var vm = new Vue();
// copy the Vue constructor.
// we can use Vue2 the same as Vue
var Vue2 = Vue;
var vm2 = new Vue2();
console.log(vm2 instanceof Vue); // true
fallenleavesguy commented 7 years ago

You should update your README.

ktsn commented 7 years ago

Yes, thanks for reporting this :)