Conversation
src/compiler/checker.ts
Outdated
| const sourceTuple: TupleType | undefined = (source as TupleTypeReference).target; | ||
| if (sourceTuple && sourceTuple.readonly && isArrayOrTupleLikeType(target) && | ||
| (!isReadonlyArrayType(target) || isTupleType(target) && !target.target.readonly)) { | ||
| !isReadonlyArrayType(target) && !(isTupleLikeType(target) && (target as TupleTypeReference).target.readonly)) { |
There was a problem hiding this comment.
A tuple-like type just needs to have a 0 property, so this cast isn't safe.
There was a problem hiding this comment.
Alternative is just to dumb down the error message and check if it's strictly a tuple type or array type that isn't readonly, only then giving the adjusted error message
There was a problem hiding this comment.
Sorry, was abit confused by the comment on isTupleLikeType.
There was a problem hiding this comment.
Does this check give the right error message for the following?
interface MyTupleLike { readonly 0: string }
let x: MyTupleLike = [10000] as const;There was a problem hiding this comment.
To elaborate, I think we're getting close, but
isArrayOrTupleLikeType(target)probably needs to be replaced with something like
(isArrayType(target) || isTupleType(target))so get rid of the Like
There was a problem hiding this comment.
The error message is now:
Type 'readonly [10000]' is not assignable to type 'MyTupleLike'.
Types of property '0' are incompatible.
Type '10000' is not assignable to type 'string'. [2322]There was a problem hiding this comment.
Some other baseline changes that remove: ... pop, push, concat, and 16 more.. Is that reasonable?
fa4828e to
393be5d
Compare
| tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(18,5): error TS2741: Property '2' is missing in type '[string, number]' but required in type '[number, number, number]'. | ||
| tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(19,5): error TS2741: Property '2' is missing in type 'StrNum' but required in type '[number, number, number]'. | ||
| tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2740: Type '{ 0: string; 1: number; length: 2; }' is missing the following properties from type '[number, number, number]': 2, pop, push, concat, and 16 more. | ||
| tests/cases/conformance/types/tuple/arityAndOrderCompatibility01.ts(20,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number, number, number]'. |
There was a problem hiding this comment.
I wonder if it would be nice here to look for pairs of tuple-like things and elaborate if the lengths do not match? (Maybe not for this PR).
There was a problem hiding this comment.
I think if there's a known length property, that's likely good enough
| const at3: readonly number[] = [1]; | ||
| const at4: [1] = at3; | ||
| ~~~ | ||
| !!! error TS2740: Type 'readonly number[]' is missing the following properties from type '[1]': 0, pop, push, reverse, and 4 more. |
There was a problem hiding this comment.
How come this one doesn't get the readonly error message?
There was a problem hiding this comment.
The condition for readonly arrays on the source only checked for arrays on the target - will change and look for tuples.
| const at3: readonly number[] = [1]; | ||
| const at4: [1] = at3; | ||
| ~~~ | ||
| !!! error TS4104: The type 'readonly number[]' is 'readonly' and cannot be assigned to the mutable type '[1]'. |
There was a problem hiding this comment.
@DanielRosenwasser This is the new message for the case you pointed out.
Fixes #35060, specifically the bug for ro-tuple to ro-tuple.
Some debate over cases like:
It might be nice to just report the length delta, but that is for a different day.