You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is the behavior in every version I tried, and I reviewed the FAQ for entries about [Type System Behavior](https://github.com/Microsoft/TypeScript/wiki/FAQ#type-system-behavior)
interfaceTest{type: "a"|"b";children: number[]|number;}typeTestArray=Omit<Test,"children">&{children: number[];};typeTestString=Test&{type: "a";};constf1=(_: TestArray)=>{};constf2=(_: TestString)=>{};(a: Test)=>{if(Array.isArray(a.children)){console.log(a.children.length);f1(a);// type error}if(a.type==="a"){f2(a);// type error}};
🙁 Actual behavior
Complain with error
Argument of type 'Test' is not assignable to parameter of type 'TestArray'.
Type 'Test' is not assignable to type '{ children: number[]; }'.
Types of property 'children' are incompatible.
Type 'number | number[]' is not assignable to type 'number[]'.
Type 'number' is not assignable to type 'number[]'.ts(2345)
Argument of type 'Test' is not assignable to parameter of type 'TestString'.
Type 'Test' is not assignable to type '{ type: "a"; }'.
Types of property 'type' are incompatible.
Type '"a" | "b"' is not assignable to type '"a"'.
Type '"b"' is not assignable to type '"a"'.ts(2345)
🙂 Expected behavior
Pass the type check, since we already checked a.children, actually compiler knows typeof a.children is number[] here, why it forget this when we treat a as a whole?
Additional information about the issue
I know we could have a user defined type guards like this
functionisTestArray(a: Test): a is TestArray{returnArray.isArray(a)}(a: Test)=>{if(isTestArray(a)){console.log(a.children.length);f1(a);// this passed}else{console.log(a.children.toFixed());// but it won't work for the other branch}};
The text was updated successfully, but these errors were encountered:
Duplicate of #42384. Due to various design limitations, type narrowings of object properties currently don't propagate to the containing object except for the special case of discriminated unions.
Yes, it is duplicated, I'm not sure it should be discussed here and #42384 .
Type guards do not propagate type narrowings to parent objects. The narrowing is only applied upon access of the narrowed property which is why the destructing function works, but the reference function does not. Narrowing the parent would involve synthesizing new types which would be expensive. More detail in this comment.
If I read correctly, it is due to performance issue so we choose not to implement this?
I think the performance issue is refer to here we won't like to generate a new type every time we checkExpression, even though actually we already have all related information to construct a coerced type here.
Correct me I'm wrong
In current design when checking if a could be called by f1(_), it would
checkExpression(node: Expression | QualifiedName): first calculate type of a, without checking deep "type relation", so it would give Test as is.
checkTypeRelatedTo(source: Type, target: Type): check if Test is compatible with TestArray, without context of a
I see now getTypeOfSourceProperty: (sym: Symbol) => Type used by propertiesRelatedTo is now setting to getNonMissingTypeOfSymbol, is it possible to switch to an Expression awareable callback on error?
🔎 Search Terms
"is not assignable", "ts(2345)"
🕗 Version & Regression Information
[Type System Behavior](https://github.com/Microsoft/TypeScript/wiki/FAQ#type-system-behavior)
⏯ Playground Link
https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgCoQM5mQbwFDLJgCeADhAFzIBEc1yAPjQEbUDcByCAFsADYATKBBBUQAVwC2zaAG0Auo2QTp0DgF88JcmkxgAglChxiyALzIA8pOBgAPOiwAaGj35CR1AHzIAZLk43QWFRZSkZKAUNDm0URzAAZTAoUABzc10sPwDCWKpadjx1DjwEAHsQLJgARgyACgB9KnjDY2IASnMfHGLSiqqAJnqmzMTktM6zbt68OrhmvUnuzmAYZDrWkwA6YAxN4jmtoI8Qds78QkJyyrK+CC2+MtTD45CHkVSwbnaOS+QauY-TiaQirdZwLaxcxmCwFc6cQgwAaA37ITS9IA
💻 Code
🙁 Actual behavior
Complain with error
🙂 Expected behavior
Pass the type check, since we already checked
a.children
, actually compiler knows typeofa.children
isnumber[]
here, why it forget this when we treata
as a whole?Additional information about the issue
I know we could have a user defined type guards like this
The text was updated successfully, but these errors were encountered: