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

Make tuple and custom array declared as interface compatible #413

Open
wants to merge 41 commits into
base: main
Choose a base branch
from

Conversation

devgony
Copy link

@devgony devgony commented Dec 18, 2022

Description: Make tuple and custom array declared as interface compatible

BREAKING CHANGE:

Related issue (if exists): To resolve #216

@CLAassistant
Copy link

CLAassistant commented Dec 18, 2022

CLA assistant check
All committers have signed the CLA.

for type_arg in extend.type_args.as_ref() {
for param in type_arg.to_owned().params {
match param {
Type::Array(array) => return Ok(Cow::Owned(Type::Array(array))),
Copy link
Author

@devgony devgony Dec 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried early return here to see what makes difference but it does not affect the result of ./scripts/test.sh arityAndOrderCompatibility at all

Is ./scripts/test.sh arityAndOrderCompatibility correct to test?

Copy link
Member

@kdy1 kdy1 Dec 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add Type::Interface to

Type::Conditional(..)
| Type::IndexedAccessType(..)
| Type::Alias(..)
| Type::Instance(..)
| Type::Intrinsic(..)
| Type::Mapped(..)
| Type::Operator(Operator {
op: TsTypeOperatorOp::KeyOf,
..
}) => {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command itself is correct

@kdy1 kdy1 added this to the 1. No false positive milestone Dec 18, 2022
@kdy1 kdy1 self-assigned this Dec 18, 2022
@devgony
Copy link
Author

devgony commented Dec 19, 2022

$ ./scripts/test.sh arityAndOrderCompatibility

2 unmatched errors out of 17 errors. Got 5 extra errors.
Wanted: [RefError { line: 19, column: 5, code: "TS2741" }, RefError { line: 22, column: 5, code: "TS2741" }]
Unwanted: [(19, "TS2322"), (22, "TS2322"), (30, "TS2322"), (34, "TS2322"), (35, "TS2322")]

I made it to remove (16, "TS2461").
Should i remove all the other 5 extra errors In this issue? 😢

@kdy1
Copy link
Member

kdy1 commented Dec 19, 2022

No, it's okay to split PRs. I'll review this PR once you undraft it.

@devgony
Copy link
Author

devgony commented Dec 20, 2022

I'm trying to solve nested_assignment error in advance of undraft but cannot get which part is wrong yet.

}) => {
for extend in extends {
let types = extend.to_owned().type_args.into_iter().flat_map(|cur| cur.params);
let union_type = Type::new_union(*span, types);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It almost solved nest_assignment errors but not RegExpExecArray yet.
Could you give me any hint where to get RegExpExecArray type to return Array?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RegExpExecArray is declared as

interface RegExpExecArray extends Array<string> {
    index: number;
    input: string;
}

So you need to check the type arguments of Array

@kdy1 kdy1 removed their assignment Jan 10, 2023
@devgony devgony marked this pull request as ready for review January 14, 2023 11:22
@kdy1
Copy link
Member

kdy1 commented Jan 14, 2023

Can you sign the CLA?

@kdy1 kdy1 self-assigned this Jan 14, 2023
Copy link
Member

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

for extend in extends {
let types = extend.to_owned().type_args.into_iter().flat_map(|cur| cur.params);
let union_type = Type::new_union(*span, types);
if let box RExpr::Ident(ident) = &extend.expr {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should check for Type::Array after using self.type_of_ts_entity_name

@@ -117,6 +116,22 @@ impl Analyzer<'_, '_> {
| Type::EnumVariant(..)
| Type::Param(_)
| Type::Module(_) => return Ok(ty),
Type::Interface(Interface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this approach is wrong

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean we should add more condition here to decrease the range of match arm?
Or It is totally wrong location to implement?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the latter

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give any tips like where to start first?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some match expressions should be added to

tracker,
}) => {
for parent in extends {
let parent = self.type_of_ts_entity_name(parent.span(), &parent.expr, parent.type_args.as_deref())?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A user can add methods to their own array type.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this does not handle tuple types correctly

@kdy1 kdy1 removed their assignment Jan 15, 2023
@devgony devgony requested a review from kdy1 February 1, 2023 09:05
metadata: InterfaceMetadata { common },
tracker,
}) => {
for parent in extends {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic is too naive

}) => {
for parent in extends {
let ty = self.type_of_ts_entity_name(parent.span(), &parent.expr, parent.type_args.as_deref())?;
if let Type::Array(_) = &ty {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking for Type::Array is not enough, and we should handle this by accessing iterating over properties

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interface MyTuple extends Array<unknown> {
    0: number
    1: number
}

declare let a: MyTuple
declare let b: [number, number]

a = b // ok
b = a // error

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgLIE8AqBXADgGxQgA9IQATAZ2QEEoo50AebEAaxAHsB3EAPmQBvAFDIxyAAwAuZCGwBbAEbRR4gIwy5SlQF9hw8hAT44UFITDI4MjDgIQDRk2eQXkimQG0tyqABpZBV8AXX04ZABed2QAehjkTjZhRUirWPjoKE4oIA

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interface MyTuple extends Array<any> {
    0: number
    1: number
}

declare let a: MyTuple
declare let b: [number, number]

a = b // ok
b = a // error

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgLIE8AqBXADgGxQgA9IQATAZ2QEEoo50AeOEdAPmQG8AoZf5AAYAXMhDYAtgCNofAQEZR46bIC+PHuQgJ8cKCkJhkcURhwEIm7bv3JDyKaIDaymVAA0YyW4C6GuMgAvA7IAPShyAD2ANY8UkHGYRHQUJFQQA

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you can see, we can't rely on the type argument in extends Array<T>

{
println!("@@@\n{lkind:#?}:{rkind:#?}");
let diff = lkind == rkind;
println!("@@@\n{diff}");
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Is there any existing function to compare two KeywordType and return reasonable error?
  2. Do you think I'm going correct way?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. You can use assign_with_opts(...)? to do it
  2. I think you should not reimplement whole logic here, but delegate to a recursive call to assign_with_opts

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we should keep logic here.
Otherwise, it breaks other tests
https://github.com/dudykr/stc/actions/runs/4110781244/jobs/7093929846

@kdy1
Copy link
Member

kdy1 commented Jun 3, 2023

Adding more tests would be awsome. Thank you!

@kdy1
Copy link
Member

kdy1 commented Jun 3, 2023

Adding more tests would be awesome. Thank you!

// x = z; // should get TS2322 but pass
y = x;
y = z;
// z = x; // should pass but got TS2322
Copy link
Author

@devgony devgony Jun 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to TS Playground,
It seems that x = z and z = x work in opposite directions.
Should I follow TS playground and fix it in this PR?
image
TSPlayground

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this issue is related to the following issue @kdy1
#1005

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sunrabbit123
Thanks for the information.
So it looks like it does not need to be fixed, at least in this PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

z = x must be not emit 2322
x = z must be emit 2322

I think the code is fine.

And it seems to be out of the conventional test case.

When I commented above, I thought it was an existing test case.
I'm sorry.

required_error: 874,
matched_error: 1749,
extra_error: 284,
panic: 20,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you run check.sh agian?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got thread 'conformance::types::uniqueSymbol::uniqueSymbolsDeclarations.ts' has overflowed its stack
Should i pass some option to avoid the overflow?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way is simple

  1. Check that the code you wrote affects stackoverflow.
  2. If it does, insert some stackguards.
  3. if it doesn't, it's broken and you can report it in an issue

Thanks you


The following code detects the overflow and handles it.

let _stack = match stack::track(actual_span) {
                Ok(v) => v,
                Err(err) => {
                    // print_backtrace();
                    return Err(err.into());
                }
            };

Copy link

changeset-bot bot commented Dec 29, 2023

⚠️ No Changeset found

Latest commit: ed10347

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@devgony devgony requested a review from kdy1 December 29, 2023 04:30
@@ -33,3 +33,8 @@ var n3: [number, string] = z;
var o1: [string, number] = x;
var o2: [string, number] = y;
var o3: [string, number] = y;

x = y;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test file is copied from the official tsc conformance test suite, so we should not modify it.

@devgony devgony requested a review from kdy1 December 29, 2023 06:02
Copy link
Member

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like this PR does not improve the test stats?

@devgony devgony requested a review from kdy1 January 26, 2024 08:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Make tuple and custom array declared as interface compatible
4 participants