mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
Accept optional checked-dynamic parameters in generic method instances (#1421)
This commit is contained in:
@@ -408,7 +408,15 @@ export function paramShapes(
|
||||
return { type: mapped, mode: "rest" };
|
||||
}
|
||||
if (declParam.initializer) return defaultParameterShape(lowerer, declParam, mapped);
|
||||
if (declParam.questionToken && !lowerer.bareUndefinedArmedUnion(mapped)) {
|
||||
// A checked-value slot holds undefined directly, so an omitted
|
||||
// argument needs no union arm (paramShape's declared-signature rule;
|
||||
// an erased type parameter and a class-implemented interface view
|
||||
// both map here).
|
||||
if (
|
||||
declParam.questionToken &&
|
||||
!lowerer.bareUndefinedArmedUnion(mapped) &&
|
||||
mapped.kind !== "dyn"
|
||||
) {
|
||||
lowerer.unsupported(
|
||||
"SC1090",
|
||||
declParam,
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/6340-prototype-reflection-optional-view-param.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// A generic method whose optional parameter is an interface view (or an
|
||||
// erased type parameter) reflects through the prototype of an instance
|
||||
// that crossed into checked-dynamic code, and calls directly with the
|
||||
// argument omitted.
|
||||
interface Handle {
|
||||
close(): string;
|
||||
}
|
||||
class Plain implements Handle {
|
||||
close(): string {
|
||||
return "closed";
|
||||
}
|
||||
}
|
||||
class Registry {
|
||||
private current: Handle | null = null;
|
||||
use(handle: Handle | null): void {
|
||||
this.current = handle;
|
||||
}
|
||||
wrap<F>(fn: F, handle?: Handle | null): F {
|
||||
if (handle) this.current = handle;
|
||||
return fn;
|
||||
}
|
||||
tag<T>(value: T, label?: T): string {
|
||||
return `${String(value)}:${label === undefined ? "none" : String(label)}`;
|
||||
}
|
||||
size(): number {
|
||||
return this.current === null ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
const registry = new Registry();
|
||||
const inc = registry.wrap((x: number) => x + 1);
|
||||
console.log(inc(1), registry.size());
|
||||
const dec = registry.wrap((x: number) => x - 1, new Plain());
|
||||
console.log(dec(1), registry.size());
|
||||
console.log(registry.tag(1), registry.tag("a", "b"));
|
||||
|
||||
const boxed: unknown = registry;
|
||||
const proto = Object.getPrototypeOf(boxed);
|
||||
console.log(Object.getOwnPropertyNames(proto).join(","));
|
||||
console.log(typeof proto.wrap, typeof proto.tag, proto.size.call(registry));
|
||||
const loose: any = registry;
|
||||
console.log(loose.size(), proto.tag.call(registry, 2), proto.tag.call(registry, 2, 3));
|
||||
Reference in New Issue
Block a user