Repository navigation
Control flow analysis for destructured rest element of discriminated union #46680
Copy link
Copy link
Open
Labels
In DiscussionNot yet reached consensusNot yet reached consensusSuggestionAn idea for TypeScriptAn idea for TypeScript
Description
Activity
Yeah, might be nice to support. Though it's an expensive way to do it as you're incurring an extra object allocation.
Yep, but par for the course for contexts like React where you might extract some props and forward the rest
import React from 'react' type Props = | ({ as: "div" } & React.ComponentPropsWithRef<"div">) | ({ as: "span" } & React.ComponentPropsWithRef<"span">) function Component({ as, ...rest }: Props) { if (as === 'div') { return <div {...rest} /> } if (as === 'span') { return <span {...rest} /> } // I think something like https://github.com/microsoft/TypeScript/issues/30581 would let us just do: // return <as {...rest} /> }
Reacted by Steven Luscher, Sébastien Lorber, João Ferreira and Onyedikachi OzoaniCan confirm this looks like something React devs do
Reacted by Sébastien Lorber, Mateus Vahl, Oleksandr Vinohradov, Sebastian Andil, jp2masa, Mike Holloway, Magoz, Fernando Greco, Steven Luscher, ortophius and 2 moreReacted by lazytype, Tiago Alves, ortophius and nvmnghia- addedIn DiscussionNot yet reached consensusNot yet reached consensusSuggestionAn idea for TypeScriptAn idea for TypeScript
on Nov 4, 2021 FYI, this is not only a React pattern, we would like to be able to write something like the following, based on #47190:
type Message = { method: string, args: unknown[], result?: string, }; type KernelDeliveryMessage = [tag: 'message', target: string, msg: Message]; type KernelDeliveryNotify = [tag: 'notify', resolutions: string[] ]; type KernelDeliveryObject = KernelDeliveryMessage | KernelDeliveryNotify; declare function translateMessage(target: string, msg: Message): any; declare function translateNotify(resolutions: string[]): any; type KernelDeliveryToVatDelivery = (...args: KernelDeliveryObject) => any; const kernelDeliveryToVatDelivery:KernelDeliveryToVatDelivery = (type,...args) => { switch (type) { case 'message': return translateMessage(...args); case 'notify': return translateNotify(...args); default: throw new Error(`unknown kernelDelivery.type ${type}`); } }
Output
"use strict"; const kernelDeliveryToVatDelivery = (type, ...args) => { switch (type) { case 'message': return translateMessage(...args); case 'notify': return translateNotify(...args); default: throw new Error(`unknown kernelDelivery.type ${type}`); } };
Compiler Options
{ "compilerOptions": { "strict": true, "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, "strictBindCallApply": true, "noImplicitThis": true, "noImplicitReturns": true, "alwaysStrict": true, "esModuleInterop": true, "declaration": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "target": "ES2017", "module": "ESNext", "moduleResolution": "node" } }Playground Link: Provided
Reacted by Joe Calzaretta, Turadg Aleahmad, Trevor Hartman, Faisal Rahman, Magoz, Steven Luscher, ortophius, Ivo Todorov and nvmnghia- added a commit that references this issue
on Oct 30, 2023
Metadata
Metadata
Assignees
Labels
In DiscussionNot yet reached consensusNot yet reached consensusSuggestionAn idea for TypeScriptAn idea for TypeScript
Suggestion
🔍 Search Terms
rest spread element destructure destructuring discriminated union narrow refine
✅ Viability Checklist
My suggestion meets these guidelines:
⭐ Suggestion
A natural extension of #46266 would be to support the following
📃 Motivating Example
💻 Use Cases