TypeScript Version: 3.7.2
I'm seeing incorrect behavior when I extend a computed type that's more than a few levels deep. When I explicitly define the type, I don't see the same behavior. I'm guessing that complex types are getting implicitly cast to any in this circumstance – tsc should probably either instantiate the correct type or cast them to unknown with a warning when they're too big.
This is admittedly a contrived example but I've run into similar issues when, for example, developing https://github.com/ostrowr/ts-json-validator
Search Terms:
depth, conditional types, extends, implicit any
Expected behavior:
shouldBeFalse and correctlyFalseWhenExpanded are both false (see code snippet below)
Actual behavior:
shouldBeFalse is True (i.e. 6 == 5 in my contrived version of Peano arithmetic)
Related Issues:
Code
typeNatural={prev: Natural}typeZero={prev: never}typeEquals<AextendsNatural,BextendsNatural>=AextendsB ?
BextendsA ?
true :
false : falsetypeS<TextendsNatural>={prev: T}typeOne=S<Zero>typeTwo=S<One>typeThree=S<Two>typeFour=S<Three>typeFive=S<Four>typeFiveByHand={// this is the exact same type as Five, just manually expandedprev: {prev: {prev: {prev: {prev: {prev: never;};};};};};}typeSix=S<Five>typeSixByHand={// this is the exact same type as Six, just manually expandedprev: {prev: {prev: {prev: {prev: {prev: {prev: never;};};};};};};}typecorrectlyFalseForShallowTypes=Equals<Four,Five>// type: falsetypecorrectlyTrue=Equals<Four,Four>// type: truetypeshouldBeFalse=Equals<Five,Six>// type: true (should be false!)typecorrectlyFalseWhenExpanded=Equals<FiveByHand,SixByHand>// type: false (as expected)Output
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": false,
"allowJs": false,
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES2017",
"module": "ESNext"
}
}Playground Link:Provided
TypeScript Version: 3.7.2
I'm seeing incorrect behavior when I
extenda computed type that's more than a few levels deep. When I explicitly define the type, I don't see the same behavior. I'm guessing that complex types are getting implicitly cast toanyin this circumstance – tsc should probably either instantiate the correct type or cast them tounknownwith a warning when they're too big.This is admittedly a contrived example but I've run into similar issues when, for example, developing https://github.com/ostrowr/ts-json-validator
Search Terms:
depth, conditional types, extends, implicit any
Expected behavior:
shouldBeFalseandcorrectlyFalseWhenExpandedare bothfalse(see code snippet below)Actual behavior:
shouldBeFalseis True (i.e. 6 == 5 in my contrived version of Peano arithmetic)Related Issues:
Code
Output
Compiler Options
{ "compilerOptions": { "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, "strictBindCallApply": true, "noImplicitThis": true, "noImplicitReturns": true, "useDefineForClassFields": false, "alwaysStrict": true, "allowUnreachableCode": false, "allowUnusedLabels": false, "downlevelIteration": false, "noEmitHelpers": false, "noLib": false, "noStrictGenericChecks": false, "noUnusedLocals": false, "noUnusedParameters": false, "esModuleInterop": true, "preserveConstEnums": false, "removeComments": false, "skipLibCheck": false, "checkJs": false, "allowJs": false, "declaration": true, "experimentalDecorators": false, "emitDecoratorMetadata": false, "target": "ES2017", "module": "ESNext" } }Playground Link:Provided