Skip to content
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

Assigning to field with a union type across functions #18

Closed
xbgnx opened this issue Mar 29, 2023 · 4 comments
Closed

Assigning to field with a union type across functions #18

xbgnx opened this issue Mar 29, 2023 · 4 comments
Labels
checking Issues around checking
Milestone

Comments

@xbgnx
Copy link

xbgnx commented Mar 29, 2023

Where I can try Ezno? Please add some online sandbox where I can try Ezne online
Here is interesting example that makes you think about whole soundness of type checking

function anotherFunc<T extends {field: string | null}>(obj: T){
    obj.field = null;
};

function someFunc<T extends {field: string}>(obj: T){
    obj.field;
    anotherFunc(obj);
    obj.field.length;
};

Does Ezno handle error in this example? (TypeScript doesn't). Here we have a runtime error because caller sets "obj.field = null" but callee does not expect this value. I think typecheker needs to calculate diff between passed type and type declared in parameter signature and make sure nothing from this diff set of values does not assign to parameter in the body of function in order to prevent runtime error. What do you think?

@kaleidawave kaleidawave changed the title Can Ezno type checker recognize this error? Assigning to field with a union type across functions Mar 29, 2023
@kaleidawave
Copy link
Owner

kaleidawave commented Mar 29, 2023

Where I can try Ezno? Please add some online sandbox where I can try Ezne online

Currently not public, will be by the summer hopefully when I have more time.

Here is interesting example that makes you think about whole soundness of type checking

Yes this is an interesting issue that is really important for type safety. Under the type rules (which follow TypeScript), it is valid to pass obj to anotherFunc. And while this passes under the rules of TypeScript it will throw at runtime as there is no property .length on null.

Haven't tested but it all the data should be present as Ezno does track mutation effects. I think it would throw a property does not exist on the obj.field.length line.

@kaleidawave kaleidawave added the checking Issues around checking label Mar 29, 2023
@kaleidawave
Copy link
Owner

Interestingly this is solved in Flow because they do not accept passing a general type to a union type.

https://flow.org/try/#1N4Igxg9gdgZglgcxALmAXwDTggEwKYogwCuUYALnNAAQCGUE5AFngE4BipYAPACrXJqweHgA2OQQGdyrOFATUAPtSjFRotAD4AFBABGAK0G8AlMAA6UateoB6W9X0GAdCPHUAvCrWiA3JZtqSChJCFE8Z1EIBG1zECY4OJNLNH8oSxIyShpQgFs8TjI+ASE3CWppWXktXUNjMwCbJ1c4MRw0wPpGFg4uWoMTDqbDFrbIvHlmNNSQLAA3NkkqKEI5gAZnACY1zecARhA0IA

I don't like this behaviour and diverges from TS. So effects are the way to go here

@kaleidawave kaleidawave added this to the 0.1.0 milestone Jun 23, 2023
@kaleidawave
Copy link
Owner

This sort of works. Given

const x = { a: 2 }
function updateA(obj: { a: string | number }) {
    obj.a = "hi"
}
updateA(x)
const y: number = x.a

It errors with Type "hi" is not assignable to type number. See specification.md#updating-property

Need to test with arrays and currently doesn't respect if x has an assingment restriction, so not perfect yet

@kaleidawave
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
checking Issues around checking
Projects
None yet
Development

No branches or pull requests

2 participants