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

Template literal type printing #188

Closed
kaleidawave opened this issue Aug 13, 2024 · 5 comments · Fixed by #218
Closed

Template literal type printing #188

kaleidawave opened this issue Aug 13, 2024 · 5 comments · Fixed by #218
Assignees
Labels
diagnostics related to outputting code errors enhancement New feature or request good-second-issue Moderately difficult issue

Comments

@kaleidawave
Copy link
Owner

At the moment the template literal type `Hi${string}` is printed at string (as that is its base type).

There should be special logic to pick up the type Constructor::BinaryOperation { lhs, rhs, operation: MathematicalAndBitwise::Addition } and then form a chain of parts: Vec<(String, TypeId)>, trailing: String using recursive type traversal. If it looks like a template literal type (aka no number + number) then it can be printed like on (see example in parser)

It should be added around here

Constructor::ConditionalResult {
condition,
truthy_result,
otherwise_result,
result_union: _,
} => {
// TODO nested on constructor
let is_standard_generic = matches!(
types.get_type_by_id(*condition),
Type::RootPolyType(
PolyNature::InferGeneric { .. }
| PolyNature::MappedGeneric { .. }
| PolyNature::FunctionGeneric { .. }
| PolyNature::StructureGeneric { .. }
)
);
if debug || is_standard_generic {
if debug {
write!(buf, "?#{} ", ty.0).unwrap();
}
print_type_into_buf(*condition, buf, cycles, args, types, info, debug);
buf.push_str(" ? ");
}
print_type_into_buf(*truthy_result, buf, cycles, args, types, info, debug);
buf.push_str(if debug || is_standard_generic { " : " } else { " | " });
print_type_into_buf(*otherwise_result, buf, cycles, args, types, info, debug);
}

@kaleidawave kaleidawave added enhancement New feature or request good-second-issue Moderately difficult issue diagnostics related to outputting code errors labels Aug 13, 2024
@kaleidawave kaleidawave changed the title Slice printing Template literal type printing Aug 13, 2024
@sor4chi
Copy link
Contributor

sor4chi commented Nov 9, 2024

Hello @kaleidawave, next I am working on this.

#### `as` rewrite
```ts
type PrefixKeys<T> = {
[P in ((keyof T) & string) as `property_${P}`]: T[P];
};
interface X { a: number };
declare let x: PrefixKeys<X>;
x.property_a satisfies number;
x.property_b
```
- No property 'property_b' on { [string]: X[keyof X & string] }

When implementing type expansion in template literals, this case fails, but how far do you expect to expand?

// Current
No property 'property_b' on { [string]: X[keyof X & string] }

// Option 1
No property 'property_b' on { [`property_${P}`]: X[keyof X & string] }

// Option 2
No property 'property_b' on { [`property_${((keyof T) & string)}`]: X[keyof X & string] }

// Option 3
No property 'property_b' on { [`property_${((keyof X) & string)}`]: X[keyof X & string] }

Current implementation is Option 3 #218 (draft)

@kaleidawave
Copy link
Owner Author

Awesome! Yes I like option 3 as it has the most information. (is there any difference between 2 and 3?). It is fine to modify the specification if it is just a printing difference etc.

@sor4chi
Copy link
Contributor

sor4chi commented Nov 9, 2024

It is simply a question of how deep to search, so if Option 3 is fine, this seems to be the way to go!

Incidentally, this is how this case currently works, but it is also supposed to be deployed, right?


```ts
const invalidStr: `Hi${string}` = 'Hello, there!';
type InvalidStr = `Hi${string}`;
const invalidStr2: InvalidStr = 'Hello, there2!';
```

- Type "Hello, there!" is not assignable to type `Hi${string}`
- Type "Hello, there2!" is not assignable to type InvalidStr

@kaleidawave
Copy link
Owner Author

Yep I think that is fine. I am split on whether to print the name vs the value of an alias. I think it currently easiest to just print the name.

@sor4chi
Copy link
Contributor

sor4chi commented Nov 9, 2024

OK, so I'm going to Open the PR as it is for now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
diagnostics related to outputting code errors enhancement New feature or request good-second-issue Moderately difficult issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants