You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
typescript conditional type with different constructors signatures
typescript conditional type with enum example
Code
// A *self-contained* demonstration of the problem follows...// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.enumFood{SANDWICH,SOUP}interfaceMealPrep<FoodType>{makeFood(): FoodType}classSandwich{constructor(privatereadonlyingredients: string[]){}}classSoup{constructor(privatereadonlyingredients: string[]){}}classSandwichServiceimplementsMealPrep<Sandwich>{constructor(privatereadonlyfoo: number){}makeFood(): Sandwich{returnnewSandwich(['ham','cheese']);}}classSoupServiceimplementsMealPrep<Soup>{constructor(privatereadonlyfoo: string){}makeFood(): Soup{returnnewSoup(['tomato','crouton']);}}typeNarrowedFood<TextendsFood>=TextendsFood.SOUP ? SoupService :
TextendsFood.SANDWICH ? SandwichService :
never// Is it possible to narrow this type or structure this in a way that avoids unions?functiongetMealPrep<TextendsFood>(food: T): NarrowedFood<T>{switch(food){caseFood.SOUP:
returnnewSoupService('example of varying constructor signature')caseFood.SANDWICH:
returnnewSandwichService(123)}}constexample=getMealPrep(Food.SANDWICH)constsandwich=example.makeFood()// does correctly resolve to Sandwich
I would like to use an enum to construct one of a fixed set of types and then use a conditional type to narrow the return value to a single type that's relevant for a given branch of an enum.
In the example above, if I supply getMealPrep(Food.SOUP) I would like the inference engine to understand that I will get back a SoupService instance. This works as expected when SoupService and SandwichService have the same constructor signatures, however, when the signatures of SoupService and SandwichService differ I get the error Returned expression type SoupService is not assignable to type NarrowedFood<T>.
Expected behavior:
I would expect not to receive an error in getMealPrep when SoupService and SandwichService have different constructor type signatures.
TypeScript Version: 3.7.x-dev.201xxxxx
Reproduced Issue with TS Nightly: http://www.typescriptlang.org/play/?ts=3.8.0-dev.20191125#code/KYOwrgtgBAYg9nAJlA3gKCpgygQQHIAiA6gJIDCAEgDQbYDyAqgApoC+aAliAC7ABOAMwCGAY2BQAssCEAbJn2AAHADzwkAFQCei4AD5UtKBCEBrYGsQAKAJQAuWAkRadbNCJlCAzp6hYhIRAB3DhEACwNMTBE4EE9uPjARbjg+S0U+DgA3IV4oBSFEGJlNKC4AcwVEDlBuT3s4jJAygG0AXWtUKHZ2dy8fLDgwRQiomIbE5NT0rJzxfMKQYtKmyuqeOqgG8raOlC7XXu9ffyCQ0Kx+TJDxDghFGWAIGp8pWXklZT8A4LD9dEioNFYvEJik0hlsrl5kUSgIEPZwBAAEb8XbsAHGMwWGz2L6nMIjAGYBTcMB8EBQEDAQLHb5nSzNADkoSEEEZVCgjLCwGAnmAjPaAG5DPsDh4jgMhhc+FcxKU7g8nutJNI5AoVJLFH8RUDxkkwdNIXNpAslnC4PV4uU0SLMeZHDjfINhv8icTgKTyZTqU6hgzGcljMl2ZyRHxBskQALrMKAd00GhuNpxHghHxw4FgIgLMp1FBgAAPXgBHwWfQAXhFecLxcQpccADosIwmFAAPy+xTS2XiWxV-NF0B1hxIJv4YjkCjt2n486Xa5QPsAqmZfgJgD066gJB8HG4UEUcG8HCRDygyUpaYz59CHB8SZ0UBSmxBSTJ4m4t93FKEUECQhKT8cigIRMjgDhhzAEAODGNs0AEKCkhgikyg9V41Q+atBxLEdEF0SxzUQex1DsKBU3TOBM2zRxc21AFPGCbgCQIxxdhFAERC8cQLCbFslzdIkSTJCkqRpTVu2uSxGULVl7nEOABCgbI+E0cpATGV9Jk2DgyhAHJ30Zax2MiTi+VwsdCFISh+IEyIhK9USZx+OcZUkgBGAAmABmIy41cNAHn3c0oHLKBUO4dD3kUSweNwSzJyMoA
Search Terms:
Code
I would like to use an enum to construct one of a fixed set of types and then use a conditional type to narrow the return value to a single type that's relevant for a given branch of an enum.
In the example above, if I supply
getMealPrep(Food.SOUP)
I would like the inference engine to understand that I will get back aSoupService
instance. This works as expected whenSoupService
andSandwichService
have the same constructor signatures, however, when the signatures ofSoupService
andSandwichService
differ I get the errorReturned expression type SoupService is not assignable to type NarrowedFood<T>
.Expected behavior:
I would expect not to receive an error in
getMealPrep
whenSoupService
andSandwichService
have different constructor type signatures.Actual behavior:
Playground Link:
http://www.typescriptlang.org/play/?ts=3.8.0-dev.20191125#code/KYOwrgtgBAYg9nAJlA3gKCpgygQQHIAiA6gJIDCAEgDQbYDyAqgApoC+aAliAC7ABOAMwCGAY2BQAssCEAbJn2AAHADzwkAFQCei4AD5UtKBCEBrYGsQAKAJQAuWAkRadbNCJlCAzp6hYhIRAB3DhEACwNMTBE4EE9uPjARbjg+S0U+DgA3IV4oBSFEGJlNKC4AcwVEDlBuT3s4jJAygG0AXWtUKHZ2dy8fLDgwRQiomIbE5NT0rJzxfMKQYtKmyuqeOqgG8raOlC7XXu9ffyCQ0Kx+TJDxDghFGWAIGp8pWXklZT8A4LD9dEioNFYvEJik0hlsrl5kUSgIEPZwBAAEb8XbsAHGMwWGz2L6nMIjAGYBTcMB8EBQEDAQLHb5nSzNADkoSEEEZVCgjLCwGAnmAjPaAG5DPsDh4jgMhhc+FcxKU7g8nutJNI5AoVJLFH8RUDxkkwdNIXNpAslnC4PV4uU0SLMeZHDjfINhv8icTgKTyZTqU6hgzGcljMl2ZyRHxBskQALrMKAd00GhuNpxHghHxw4FgIgLMp1FBgAAPXgBHwWfQAXhFecLxcQpccADosIwmFAAPy+xTS2XiWxV-NF0B1hxIJv4YjkCjt2n486Xa5QPsAqmZfgJgD066gJB8HG4UEUcG8HCRDygyUpaYz59CHB8SZ0UBSmxBSTJ4m4t93FKEUECQhKT8cigIRMjgDhhzAEAODGNs0AEKCkhgikyg9V41Q+atBxLEdEF0SxzUQex1DsKBU3TOBM2zRxc21AFPGCbgCQIxxdhFAERC8cQLCbFslzdIkSTJCkqRpTVu2uSxGULVl7nEOABCgbI+E0cpATGV9Jk2DgyhAHJ30Zax2MiTi+VwsdCFISh+IEyIhK9USZx+OcZUkgBGAAmABmIy41cNAHn3c0oHLKBUO4dD3kUSweNwSzJyMoA
Related Issues:
I couldn't find any bugs that looked similar.
The text was updated successfully, but these errors were encountered: