Fixed an issue with spreading generic types with tuple constraints into calls#53615
Fixed an issue with spreading generic types with tuple constraints into calls#53615Andarist wants to merge 5 commits intomicrosoft:mainfrom
Conversation
src/compiler/checker.ts
Outdated
| else if (constraint && isTupleType(constraint)) { | ||
| forEach(getTypeArguments(constraint), (_, i) => { | ||
| const isVariable = !!(constraint.target.elementFlags[i] & ElementFlags.Variable); | ||
| const syntheticArg = createSyntheticExpression(arg, !isVariable ? getTypeOfPropertyOfType(spreadType, "" + i as __String)! : spreadType, |
There was a problem hiding this comment.
Note that this won't help with variable elements at all - there is no way to express a "deferred" type that would later skip some elements from it so a variable element gets synthesized as the whole spreadType. It isn't ideal but it also isn't worse than the current baseline.
An example code that ideally should work but it doesn't:
interface HasMethod {
method(second?: number, ...rest: boolean[]): void;
method2(first?: string, second?: number, ...rest: boolean[]): void;
}
function fn<HasMethodLike extends HasMethod>(
instance: HasMethodLike,
...args: Parameters<HasMethodLike["method"]>
) {
instance.method2('', ...args);
}There was a problem hiding this comment.
The best idea I have for fixing that is to add more information to synthetic expressions (like .skipElementCount) and then use that information in checkSyntheticExpression. This is how currently checkSyntheticExpression looks like:
function checkSyntheticExpression(node: SyntheticExpression): Type {
return node.isSpread ? getIndexedAccessType(node.type, numberType) : node.type;
}| f1(42, "hello", ...t1); | ||
| f1(42, "hello", true, ...t0); | ||
| f1(ns[0], ns[1], true); | ||
| f1(...ns, true); // FIXME: Error, since ...ns is considered as string|number here |
There was a problem hiding this comment.
many of those comments in this file were simply outdated so I updated them
fixes #53541