-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check order dependence with mutually-recursive non-unary generics #44572
Comments
It's reproducible on the playground: Playground link Deleting the unused |
Simplified and cleaned up a little to make the violation more apparent interface Parent<A> {
child: Child<A> | null;
parent: Parent<A> | null;
}
interface Child<A, B = unknown> extends Parent<A> {
readonly a: A;
// This field isn't necessary to the repro, but the
// type parameter is, so including it
readonly b: B;
}
function fn<A>(inp: Child<A>) {
// This assignability check defeats the later one
const a: Child<unknown> = inp;
}
// Allowed initialization of pu
const pu: Parent<unknown> = { child: { a: 0, b: 0, child: null, parent: null }, parent: null };
// Should error
const notString: Parent<string> = pu;
// Unsound read on .child.a
const m: string = notString.child!.a; |
Debugging notes: variance measurement for I'm not sure if any of those comparisons ever actually looked at |
@weswigham, I may need some help/advice on this one. |
We should probably make a |
The |
IIRC, when |
I've spent the last 1.5 days debugging something that looks awfully like this one. This is way beyond my head and the understanding of the type system so I can't fully assess if my issue is exactly the same or just similar. Therefore I'm going to post it, for the time being, to avoid creating a new issue that might be a duplicate of this one. code from the playgrounddeclare class StateNode<TContext, TEvent extends { type: string }> {
// if I comment out this property then error is never reported
_storedEvent: TEvent
// if I comment out this property then error is always reported
_action: ActionObject<TEvent>
// if I comment out this property then error is always reported
_state: StateNode<TContext, any>;
}
interface ActionObject<TEvent extends { type: string }> {
exec: (meta: StateNode<any, TEvent>) => void
}
export declare function createMachine<
TEvent extends { type: string }
>(action: ActionObject<TEvent>): StateNode<any, any>
export declare const execute: <TEvent extends { type: string }>(
handler: (event: TEvent) => any
) => ActionObject<TEvent>;
export declare function interpret<TContext>(
machine: StateNode<TContext, any>
): void
// uncomment to get a correct report in the `createMachine` call below
// const test: ActionObject<{ type: "PLAY"; value: number } | { type: "RESET" }> =
// {} as ActionObject<{
// type: "PLAY";
// value: number;
// }>;
const machine = createMachine({} as any);
// comment out to get a correct report in the `createMachine` call below
interpret(machine);
createMachine<{ type: "PLAY"; value: number } | { type: "RESET" }>(
execute((ev: { type: "PLAY"; value: number }) => {
console.log(ev);
})
); I've also found out that this has changed between 3.7 and 3.8. More accurately - between I know that at this point I'm probably just reiterating what you probably already know but since I've already done this detective work I'm posting this here as a reference, just in case. I also have a hunch that another issue that I've posted some months ago might be related to this one: #45859 (I would have to confirm this when this one here gets fixed) |
Bug Report
Adding an implementation of an interface allows an invalid assignability check of the interface to pass
🔎 Search Terms
assignability, unnecessary implementation
🕗 Version & Regression Information
It's still present in all versions including nightly.
⏯ Playground Link
Playground link with relevant code
Thanks @MartinJohns for the link
💻 Code
The final assignment should not pass. It accurately errors in 3.7.5, if the
Impl
class is removed (or any aspect of theiter
implementation is modified), or by adding a sentinel type likesentinel?: A
to theParent
interface to aid in type checking.🙁 Actual behavior
No error is thrown in the final assignment.
🙂 Expected behavior
A n error is throw:
The text was updated successfully, but these errors were encountered: