-
Notifications
You must be signed in to change notification settings - Fork 4
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
White-space dependent destructuring typing and renaming. Breaks backwards compatability. #33
Comments
I just realized it makes far more sense to put the type with the renamed variable. let { a: b:b } = { a: 2 }; One reads it as map Also in case it wasn't clear if the right hand side is typed one can just use typed assignment from the spec. That covers a lot of cases where the type is inferred from the right hand side function. let { a: b } := { a:uint8: 10 }; // b is type uint8. I had someone ask about this because he mentioned that most of his use cases are from function returning multiple, already typed variables. It's possible we could just not include destructuring typing at all. The main use case is where you want the type to be type casted in a compact way from the type in the right hand side object. let { a:uint32 } = { a:uint8: 10 }; Why did the language designers choose to use let { a=>b:uint32 } = { a:uint8: 10 }; The => in this case is read as "to" or "as". "Assign the value The problem is => is already a token. Then again so was |
Why you want to break syntax? Just do it like in TypeScript: const o: {a: uint8} = { a: 1 };
const { a: b }: {a: uint32} = o;
// b is uint32 |
I don't want to break any syntax. Maybe I should have been more clear that my original discussion was more of a "this can't work and needs changed". Like a number of things in the spec I wrote them quickly to create discussion. If I write something, then someone can say it's wrong and it starts the iteration. As for the TypeScript syntax, I found that slightly redundant and hard to read. (The TypeScript documentation even make this point that it's confusing). It's like a single level object schema. It's possible it could grow on me, but I don't think it's an ideal syntax. |
I think it’s not a common situation that we need to change type of variable with destructuring so it can be a bit redundant. |
I think you're probably right. I've updated the spec to include your suggestions. I do have one last issue. Do you know why TypeScript doesn't type the renamed variable, but rather the property? Seems strange to me. let { a: b = 1 }: { a:uint8 } = { a: 2 }; vs let { a: b = 1 }: { b:uint8 } = { a: 2 }; I've been staring at: let { a: b = 0, b: a = 0 }:{ a:uint8, b:uint16 } = { a: 1, b: 2 }; It doesn't sit well with me that I can't immediately create an intuitive understanding from the example. |
Maybe it’s better to use original structure than declared variables, so we describe where in it we want to change type. But it might be less redundant with deep destructuring. Both situations are much clear with deep destructuring example, like this: const o: { a: { a2: uint8 } } = { a: { a2: 1 } };
const { a: { a2: b } }: { a: { a2: uint32 } } = o; Is this clear enough if we wrote |
Okay, I think we're on the same page. Last example (probably) using arrays in objects: const { a:[, b] } = { a: [1, 2] }; And we want to type b. Do we use: const { a:[, b] }:{ a:[, uint32] } = { a: [1, 2] }; or allow: const { a:[, b:uint32] } = { a: [1, 2] }; Consider: const { a: { a2: b, a3: [, c] } }: { a: { a2: uint32, a3: [,uint8] } } = { a: { a2: 1, a3: [2, 3] } }; // b is 1, c is 3 vs: const { a: { a2: b, a3: [, c:uint8] } }: { a: { a2: uint32 } } = { a: { a2: 1, a3: [2, 3] } }; // b is 1, c is 3 |
I just found this: That whole thread goes through a lot of ideas. I have to say I did not even think of using parenthesis. His proposal B is nice. Your example becomes: const o: { a: { (a2:uint8) } } = { a: { a2: 1 } }; // deep casting
const { a: { (a2:uint32): b } } = o; My complex example becomes: const { a: { (a2:uint32): b, a3: [, c:uint8] } } = { a: { a2: 1, a3: [2, 3] } }; // b is 1, c is 3 edit: TODO: array typing when casting: const o: { (a:uint8[]) } = { a: [0, 1, 2] }; Does this work for arrays of objects? Investigate the downsides of deep casting syntax in general. |
I've added in the parenthesis grammar into the spec. I'm going to close this. I'm not sure if nested casting is a useful feature to discuss. It seems useful in cases where a function is returned and one wants to compactly modify type the object. |
Take the example below that assigns a new variable name in the destructuring assignment:
Is b a type or a new variable name? This isn't clearly defined and there's no way to infer this from the identifier.
Also consider a typed example with renaming:
Ideally the code would be white-space dependent. ": b" means renamed and ":b" would be a type. This is unconventional, but it's been my design and I had forgotten about it.
That said creating white-space dependence in this syntax is a breaking change to the spec which makes it nearly impossible to propose? That is there is probably already large amounts of code that uses renaming without a space.
It is the most elegant solution though to introduce this breaking change I believe, but I'm not sure it would be possible. Any ideas?
The text was updated successfully, but these errors were encountered: