Subscribe on changes!

Improve typings for Ref<T>

avatar
Mar 15th 2021

What problem does this feature solve?

When converting Options API code to Composition API, one often needs to convert the data to some kind of ref. However, the process is currently quite error-prone. Because a Ref object allows arbitrary indexing and returns an "any" value.

// Option API
{
  data: {
   return {
       dataList: []
   }
 }
 methods: {
    doSomething() {
        for (let i = 0; i < this.dataList.length;   i) {
            console.log(this.dataList[i])
        }
    }
 }
}
// Composition API
setup() {
    const dataList = ref<string[]>([])
    
    function doSomething() {
        // Following code can be compiled by Typescript, because dataList.length evals to "any" type.
        for (let i = 0; i < dataList.length;   i) {    // Oops, should use dataList.value.length
            console.log(dataList[i])                   // Oops, should use dataList.value[i]
        }
    }
    
    return { dataList, doSomething }
}

What does the proposed API look like?

I'm not sure how to disable the index signature at all in TypesScript, but returning null or undefined or maybe a symbol for any undeclared property should raise an error in TS.

export declare interface Ref<T = any> {
    value: T;
    /**
     * Type differentiator only.
     * We need this to be in public d.ts but don't want it to show up in IDE
     * autocomplete, so we use a private Symbol instead.
     */
    [RefSymbol]: true;
    /* Excluded from this release type: _shallow */

    // When accessing any property except value should now get a null value,
    // which will not fit in most context and TS will report errors.
    [index: string]: null
    [index: number]: null
}
avatar
Mar 16th 2021

What really happened?

image

avatar
Mar 16th 2021

What really happened?

image

I see, perhaps it's because I have noImplicitAny set to false in tsconfig.json