TypeScript
TypeScript copied to clipboard
Object.isPartOfTypeNode crashes with TypeError: Cannot read properties of undefined (reading 'kind')
Bug Report
🔎 Search Terms
Object.isPartOfTypeNode and TypeError: Cannot read properties of undefined
🕗 Version & Regression Information
- This is a crash
- This is the behaviour in every version I tried (
4.7.3,4.7.4,nextandnightlywhich was4.8.0-dev.20220804for me), and I reviewed the FAQ for entries abouttuple,recursion,tail,elimitation,depthandlimitation - I was unable to test this on prior versions because I use
4.7.3in my project
⏯ Playground Link
Playground link with relevant code
💻 Code
I reduced the codebase of ttuple to 64 lines.
type AnyArray = readonly any[];
type DigitMapping<T> = {
"0": [];
"1": [T];
"2": [T, T];
"3": [T, T, T];
"4": [T, T, T, T];
"5": [T, T, T, T, T];
"6": [T, T, T, T, T, T];
"7": [T, T, T, T, T, T, T];
"8": [T, T, T, T, T, T, T, T];
"9": [T, T, T, T, T, T, T, T, T];
};
type Multiply10<T extends AnyArray> = [
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T
];
type Add<N1 extends AnyArray, N2 extends AnyArray> = [...N1, ...N2];
type _ToTuple<
V,
S extends string,
T extends AnyArray = []
> = S extends `${infer D}${infer Rest}`
? _ToTuple<
V,
Rest,
Add<Multiply10<T>, DigitMapping<V>[D & keyof DigitMapping<V>]>
>
: [...T, ...V[], ...T];
type ToTuple<V, S extends string> = _ToTuple<V, S>;
type ElementOf<T extends AnyArray> = T extends readonly (infer V)[] ? V : never;
const length = <
T extends AnyArray,
S extends `${number}`,
R = ToTuple<ElementOf<T>, S>
>(
array: T,
condition: `>= ${S}`
): array is R extends T ? R : never => {
const expectedLength = Number(condition.split(" ")[1]);
if (array.length >= expectedLength) {
return true;
}
return false;
};
export { length };
Also the code is available in the branch here – https://github.com/Beraliv/ttuple/pull/22
🙁 Actual behaviour
➜ npm run build
> [email protected] build
> tsc --project tsconfig.json
/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:96887
throw e;
^
TypeError: Cannot read properties of undefined (reading 'kind')
at Object.isPartOfTypeNode (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:11787:25)
at _loop_15 (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:50429:51)
at createNormalizedTupleType (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:50445:31)
at createNormalizedTypeReference (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:50398:45)
at instantiateTypeWorker (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:52755:77)
at instantiateTypeWithAlias (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:52740:26)
at instantiateType (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:52726:37)
at getMappedType (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:52449:63)
at /Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:52709:92
at Object.map (/Users/beraliv/Documents/Code/ttuple/node_modules/typescript/lib/tsc.js:367:29)
🙂 Expected behaviour
➜ npm run build
> [email protected] build
> tsc --project tsconfig.json
If I replace ToTuple with _ToTuple, it starts working 🤯
As I've seen example with GetChar in release notes of TS 4.5, it should be fine to declare it this way – https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#tailrec-conditional
ℹ️ Additional information
I connected the project to node debugger and could see that in _loop_15 9th element was in the branch of tuple type (after check of isTupleType), but the length of elements.length + expandedTypes.length is 11100 (not sure what it means) so it tried to throw an error, but currentNode was undefined
A shorter repro, if possible, would be greatly appreciated if you have some spare time. Thanks!
A shorter repro, if possible, would be greatly appreciated if you have some spare time. Thanks!
Not sure if it's possible, but will try to do it this weekend
I found out 2 interesting things:
- If I replace
ToTuplewith_ToTuple, it starts working 🤯 - If I move
ToTupleto the file withlength, it also starts working
So it should be important that:
ToTupleis located in a different file- There are 2 generic types
_ToTuple(with tail recursion elimination) andToTuple
I moved all the minimal changes where it's still not working for me to this repo – https://github.com/Beraliv/ttuple-object-isPartOfTypeNode-cannot-read-kind
I will try to reduce the test case, but that's what I came up with at the moment
Here's a simplified repo in 4.7.4 workbench. You can see the error in the devtools console.
// @filename: index.ts
import { ToTuple } from "./helper";
export const fn = function<S extends string>(foo: ToTuple<any, S>): void {
}
// @filename: helper.ts
type _ToTuple<
V,
S extends string,
T extends any[]
> = S extends `${infer H}${infer Rest}`
? _ToTuple<
V,
Rest,
[...[
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T,
...T,
], 0]
>
: never;
export type ToTuple<V, S extends string> = _ToTuple<V, S, []>;
The behavior is quite weird. And here is some ways I found to make the error disappear.
- Merge the two files into a single, as @Beraliv mentioned in comment.
- Do not export
fn. - Use function declaration for
fn, not function expression. - Export
_ToTuple, even it's not imported anywhere. - Reduce the times of repeated
...T,to 3. - Remove the element
0following the repeated...T,. - Remove the first unused type parameter
Vin_ToTuple.
Thank you @whzx5byb for simplification!
- Merge the two files into a single, as @Beraliv mentioned in comment.
❌ As I have tests in the original library, it's not possible at the moment
- Do not export
fn.
❌ This function is used as public API, that's also not possible at the moment
- Use function declaration for
fn, not function expression.
✅ ~Yeah, I also tried it and it worked.~
If I use declare const length, it will work. Function overloads are also working for me
- Export
_ToTuple, even it's not imported anywhere.
✅ Yeah, at the moment I only export ToTuple and use it, replacing it with _ToTuple make it work at the moment
- Reduce the times of repeated
...T,to 3.
❌ Unfortunately, that's the only way to align numbers in string literal types with tuples. That's used in tuple validation and won't be changed (at least unless there's another way to transform '5' to [number, number, number, number, number])
- Remove the element
0following the repeated...T,
❌ The logic behind adding 0 looks a little bit more complicated than it, I cannot simply remove it at the moment, because it's a basement of the whole functionality I use for the library (same as previous point with ...T)
So there are ways to make it work so it's a non-blocker for me.
Is there anything I can help you with to make this behaviour work? I can also contribute if you don't mind. But I'm still new to the codebase and might need help
@andrewbranch hey 👋
do you need any help with the issue?
I wanted to contribute at some point, but want to understand the way it's usually done so we will be aligned and don't waste time on the unnecessary changes
Thank you in advance!
You are welcome to give it a try by following the process in https://github.com/microsoft/TypeScript/blob/main/CONTRIBUTING.md, but I have no idea how challenging it will be, and we may not be able to give you much support if you get stuck—if you end up solving it I’ll merge it, but if it seems like it will be quicker for me to just start fresh, that’s what I’ll do. That’s in contrast to “Help Wanted” and “Good First Issue” issues, where I try to offer more guidance. So you might want to look for one of those if you just want to contribute in general, but if you’re set on this issue, feel free, but at your own risk 🙂
You are welcome to give it a try by following the process in https://github.com/microsoft/TypeScript/blob/main/CONTRIBUTING.md, but I have no idea how challenging it will be, and we may not be able to give you much support if you get stuck—if you end up solving it I’ll merge it, but if it seems like it will be quicker for me to just start fresh, that’s what I’ll do. That’s in contrast to “Help Wanted” and “Good First Issue” issues, where I try to offer more guidance. So you might want to look for one of those if you just want to contribute in general, but if you’re set on this issue, feel free, but at your own risk 🙂
It sounds reasonable
I will start from “Help Wanted” and “Good First Issue” first, then will jump on this one, if it's working for you
This crash appears to have been fixed already. @typescript-bot will tell us what the fix was.
For some reason the crash isn’t reproducing in the repro runner, but it was fixed between 4.9 and 5.0.
The change between v4.9.5 and v5.0.3 occurred at 0e198c2c1d33eb97653ff51ce71e97683e22b1ed.