- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 8.9k
 
Closed
vuejs/language-tools
#4971Labels
Description
What problem does this feature solve?
We can pass type parameter in TypeScript via generics:
function <T extends string | number>doSth(value:T): T[] {
  if (value === "123") {
    return toArray(123);  // throw an error, number[] is not compatible with T[]
  }
 return toArray<T>(value)
}But we cannot do so in Vue template.
<my-select v-model="selectedFruit">
  <my-option value="🍎" />
  <my-option value="🍌" />
  <my-option value="🐘" /> // should throw an error, 🐘 is not compatible with selectedFruit 
</my-select>To make this possible, we need the ability to restrict what components can be in slot:
defineSlots({
   default: {
     accept: MyOption<T>
  }
})<my-select v-model="selectedFruit">
  <my-option value="🍎" />
  <my-option value="🍌" />
  <my-option value="🐘" /> // 🐘 is  not compatible with selectedFruit 
</my-select>also, now we have ability to prevent developer from putting unexpected components in slots!
<my-select v-model="selectedFruit as any">
   <my-radio v-model="radioValue" /> // throw an error, my-radio should not be here
</my-select>Sometimes TypeScript cannot infer acutal type we want:
<my-button-group :buttons="['🍚', '🍗']" @click="handleUpdate" />type Foods = '🍚' | '🍗';
const handleClick= (food: Foods) => {
   console.log(food);
}buttons will infer as string[], and @click handle is (value: string) => void, but we need Foods[] and (value: Foods) => void
So we also need ability to specify what type we want:
<my-button-group[Foods] :buttons="['🍚', '🍗']" @click="handleUpdate" />What does the proposed API look like?
For template:
<my-select[typeof selectedFruit] v-model="selectedFruit">
   <my-option value="🍎" />
   <my-option value="🍌" /> 
   <my-option value="🐘" /> // 🐘 is not compatible with selectedFruit 
</my-select><my-select v-generics="typeof selectedFruit" v-model="selectedFruit">
   <my-option value="🍎" />
   <my-option value="🍌" /> 
   <my-option value="🐘" /> // 🐘 is not compatible with selectedFruit 
</my-select>For slot type definition:
defineSlots({
   default: {
     accept: MyOption<T>
  }
})sxzz, sadeghbarati, longshihui, radusuciu, jd-solanki and 14 more