Argument of type 'symbol' is not assignable to parameter of type 'string | unique symbol'
Vue version
3.2.40
Link to minimal reproduction
Steps to reproduce
- Run reproduction.
- Run vue-tsc (or as configured in reproduction, use vite-plugin-checker)
What is expected?
Type checking succeeds.
What is actually happening?
Type checking fails with:
Argument of type 'symbol' is not assignable to parameter of type 'string | unique symbol'.
I am not sure why type of NONE
changes inside the template.
System Info
This is a type checking issue and not related to a particular browser.
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 16.14.2 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 7.17.0 - /usr/local/bin/npm
npmPackages:
vue: ^3.2.40 => 3.2.40
Workaround is to create two helper functions:
function onNoneChange(event: Event) {
onChange(event, NONE)
}
function stateHasNONE(): boolean {
return props.state.includes(NONE)
}
This should not be necessary.
Using NONE
instead of this.NONE
can resolve it temporarily.
Maybe you can try this as an interim solution.
// HelloWorld.tsx
import { defineComponent, PropType } from "vue";
const NONE: unique symbol = Symbol('NONE')
type State = (string | typeof NONE)[];
export default defineComponent({
props: {
state: {
type: Array as PropType<State>,
required: false
}
},
emits: {
'update:state': (state: State) => true
},
setup() {
const NONE_ERR: unique symbol = Symbol('NONE')
const onChange = (e: Event, val: typeof NONE) => {
console.log(val)
}
return {
NONE_ERR,
onChange,
}
},
render() {
type aaa = typeof this.NONE_ERR // symbol
type bbb = typeof NONE // unique symbol
return <input type="text" onClick={(e) => this.onChange(e, NONE)} />
}
})
I think the reason is typeof
can't infer the key of obejct is unique symbol
.
const thisObj = {
NONE_ERR,
onChange,
}
type RawBindings = typeof thisObj
// {
// NONE_ERR: symbol;
// onChange: (e: Event, val: typeof NONE) => void;
// }
@johnsoncodehk do you know if this bug is related to vue-tsc? It's as if the type of NONE
becomes just a regular symbol
within the template
@posva this is expected behavior because in template NONE
access via component context, and NONE
type is change from unique symbol
to symbol
in setup return. It can reproduce with:
import { defineComponent } from 'vue';
const NONE: unique symbol = Symbol('none');
const Comp = defineComponent({
setup() {
return { NONE };
},
});
onChange((new Comp()).NONE)
function onChange(id: typeof NONE) { }
A hack way is indirect expose NONE type to template:
<script lang="ts" setup>
const NONE: unique symbol = Symbol('none');
type NONE_Type = typeof NONE;
</script>
<template>
<input type="checkbox" @change="onChange($event, NONE as NONE_Type)" />
</template>
Should be closed by https://github.com/vuejs/language-tools/pull/3300