-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Allow intersected numbers in arithmetics & element access #4373
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
Changes from all commits
42a8efd
80f42ed
a31a65f
34da8c2
cad0439
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//// [intersectionArithmetic.ts] | ||
let numberObject: number & { foo: any }; | ||
let stringObject: string & { foo: any }; | ||
let numberString: number & string; | ||
|
||
let a = numberObject + 1; | ||
let b = stringObject + 1; | ||
let c = numberObject + ''; | ||
let d = stringObject + ''; | ||
let e = numberObject + stringObject; | ||
|
||
let f = numberString + 1; | ||
let g = numberString + ''; | ||
let h = numberString + numberString; | ||
|
||
let i = numberObject * 2; | ||
let j = numberString * 2; | ||
|
||
|
||
//// [intersectionArithmetic.js] | ||
var numberObject; | ||
var stringObject; | ||
var numberString; | ||
var a = numberObject + 1; | ||
var b = stringObject + 1; | ||
var c = numberObject + ''; | ||
var d = stringObject + ''; | ||
var e = numberObject + stringObject; | ||
var f = numberString + 1; | ||
var g = numberString + ''; | ||
var h = numberString + numberString; | ||
var i = numberObject * 2; | ||
var j = numberString * 2; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
=== tests/cases/conformance/types/intersection/intersectionArithmetic.ts === | ||
let numberObject: number & { foo: any }; | ||
>numberObject : Symbol(numberObject, Decl(intersectionArithmetic.ts, 0, 3)) | ||
>foo : Symbol(foo, Decl(intersectionArithmetic.ts, 0, 28)) | ||
|
||
let stringObject: string & { foo: any }; | ||
>stringObject : Symbol(stringObject, Decl(intersectionArithmetic.ts, 1, 3)) | ||
>foo : Symbol(foo, Decl(intersectionArithmetic.ts, 1, 28)) | ||
|
||
let numberString: number & string; | ||
>numberString : Symbol(numberString, Decl(intersectionArithmetic.ts, 2, 3)) | ||
|
||
let a = numberObject + 1; | ||
>a : Symbol(a, Decl(intersectionArithmetic.ts, 4, 3)) | ||
>numberObject : Symbol(numberObject, Decl(intersectionArithmetic.ts, 0, 3)) | ||
|
||
let b = stringObject + 1; | ||
>b : Symbol(b, Decl(intersectionArithmetic.ts, 5, 3)) | ||
>stringObject : Symbol(stringObject, Decl(intersectionArithmetic.ts, 1, 3)) | ||
|
||
let c = numberObject + ''; | ||
>c : Symbol(c, Decl(intersectionArithmetic.ts, 6, 3)) | ||
>numberObject : Symbol(numberObject, Decl(intersectionArithmetic.ts, 0, 3)) | ||
|
||
let d = stringObject + ''; | ||
>d : Symbol(d, Decl(intersectionArithmetic.ts, 7, 3)) | ||
>stringObject : Symbol(stringObject, Decl(intersectionArithmetic.ts, 1, 3)) | ||
|
||
let e = numberObject + stringObject; | ||
>e : Symbol(e, Decl(intersectionArithmetic.ts, 8, 3)) | ||
>numberObject : Symbol(numberObject, Decl(intersectionArithmetic.ts, 0, 3)) | ||
>stringObject : Symbol(stringObject, Decl(intersectionArithmetic.ts, 1, 3)) | ||
|
||
let f = numberString + 1; | ||
>f : Symbol(f, Decl(intersectionArithmetic.ts, 10, 3)) | ||
>numberString : Symbol(numberString, Decl(intersectionArithmetic.ts, 2, 3)) | ||
|
||
let g = numberString + ''; | ||
>g : Symbol(g, Decl(intersectionArithmetic.ts, 11, 3)) | ||
>numberString : Symbol(numberString, Decl(intersectionArithmetic.ts, 2, 3)) | ||
|
||
let h = numberString + numberString; | ||
>h : Symbol(h, Decl(intersectionArithmetic.ts, 12, 3)) | ||
>numberString : Symbol(numberString, Decl(intersectionArithmetic.ts, 2, 3)) | ||
>numberString : Symbol(numberString, Decl(intersectionArithmetic.ts, 2, 3)) | ||
|
||
let i = numberObject * 2; | ||
>i : Symbol(i, Decl(intersectionArithmetic.ts, 14, 3)) | ||
>numberObject : Symbol(numberObject, Decl(intersectionArithmetic.ts, 0, 3)) | ||
|
||
let j = numberString * 2; | ||
>j : Symbol(j, Decl(intersectionArithmetic.ts, 15, 3)) | ||
>numberString : Symbol(numberString, Decl(intersectionArithmetic.ts, 2, 3)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
=== tests/cases/conformance/types/intersection/intersectionArithmetic.ts === | ||
let numberObject: number & { foo: any }; | ||
>numberObject : number & { foo: any; } | ||
>foo : any | ||
|
||
let stringObject: string & { foo: any }; | ||
>stringObject : string & { foo: any; } | ||
>foo : any | ||
|
||
let numberString: number & string; | ||
>numberString : number & string | ||
|
||
let a = numberObject + 1; | ||
>a : number | ||
>numberObject + 1 : number | ||
>numberObject : number & { foo: any; } | ||
>1 : number | ||
|
||
let b = stringObject + 1; | ||
>b : string | ||
>stringObject + 1 : string | ||
>stringObject : string & { foo: any; } | ||
>1 : number | ||
|
||
let c = numberObject + ''; | ||
>c : string | ||
>numberObject + '' : string | ||
>numberObject : number & { foo: any; } | ||
>'' : string | ||
|
||
let d = stringObject + ''; | ||
>d : string | ||
>stringObject + '' : string | ||
>stringObject : string & { foo: any; } | ||
>'' : string | ||
|
||
let e = numberObject + stringObject; | ||
>e : string | ||
>numberObject + stringObject : string | ||
>numberObject : number & { foo: any; } | ||
>stringObject : string & { foo: any; } | ||
|
||
let f = numberString + 1; | ||
>f : number | ||
>numberString + 1 : number | ||
>numberString : number & string | ||
>1 : number | ||
|
||
let g = numberString + ''; | ||
>g : string | ||
>numberString + '' : string | ||
>numberString : number & string | ||
>'' : string | ||
|
||
let h = numberString + numberString; | ||
>h : number | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is very "interesting" behavior. I'm not sure what the correct thing to do here would be, but even the spec says that there are no meaningful values for intersections of primitives. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what the best behavior is here, but given that there is no way in JavaScript to create a type that is both a string and a number, it doesn't matter very much in my opinion. I think the question we should ask is: which of these rules should be used?
In case 1, the result should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only values that are both a number and a string are undefined + undefined = NaN
undefined + null = NaN
null + undefined = NaN
null + null = 0 All results are numbers, so I think the current behavior is correct. |
||
>numberString + numberString : number | ||
>numberString : number & string | ||
>numberString : number & string | ||
|
||
let i = numberObject * 2; | ||
>i : number | ||
>numberObject * 2 : number | ||
>numberObject : number & { foo: any; } | ||
>2 : number | ||
|
||
let j = numberString * 2; | ||
>j : number | ||
>numberString * 2 : number | ||
>numberString : number & string | ||
>2 : number | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//// [intersectionElementAccess.ts] | ||
let numberObject: number & { foo: any }; | ||
let stringObject: string & { foo: any }; | ||
let numberString: number & string; | ||
|
||
let object: { | ||
[ index: number ]: { stringIndexer: any, numberIndexer: any }, | ||
[ key: string]: { stringIndexer: any } | ||
} | ||
|
||
let a = object[numberObject]; | ||
let b = object[stringObject]; | ||
let c = object[numberString]; | ||
|
||
|
||
//// [intersectionElementAccess.js] | ||
var numberObject; | ||
var stringObject; | ||
var numberString; | ||
var object; | ||
var a = object[numberObject]; | ||
var b = object[stringObject]; | ||
var c = object[numberString]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
=== tests/cases/conformance/types/intersection/intersectionElementAccess.ts === | ||
let numberObject: number & { foo: any }; | ||
>numberObject : Symbol(numberObject, Decl(intersectionElementAccess.ts, 0, 3)) | ||
>foo : Symbol(foo, Decl(intersectionElementAccess.ts, 0, 28)) | ||
|
||
let stringObject: string & { foo: any }; | ||
>stringObject : Symbol(stringObject, Decl(intersectionElementAccess.ts, 1, 3)) | ||
>foo : Symbol(foo, Decl(intersectionElementAccess.ts, 1, 28)) | ||
|
||
let numberString: number & string; | ||
>numberString : Symbol(numberString, Decl(intersectionElementAccess.ts, 2, 3)) | ||
|
||
let object: { | ||
>object : Symbol(object, Decl(intersectionElementAccess.ts, 4, 3)) | ||
|
||
[ index: number ]: { stringIndexer: any, numberIndexer: any }, | ||
>index : Symbol(index, Decl(intersectionElementAccess.ts, 5, 2)) | ||
>stringIndexer : Symbol(stringIndexer, Decl(intersectionElementAccess.ts, 5, 21)) | ||
>numberIndexer : Symbol(numberIndexer, Decl(intersectionElementAccess.ts, 5, 41)) | ||
|
||
[ key: string]: { stringIndexer: any } | ||
>key : Symbol(key, Decl(intersectionElementAccess.ts, 6, 2)) | ||
>stringIndexer : Symbol(stringIndexer, Decl(intersectionElementAccess.ts, 6, 18)) | ||
} | ||
|
||
let a = object[numberObject]; | ||
>a : Symbol(a, Decl(intersectionElementAccess.ts, 9, 3)) | ||
>object : Symbol(object, Decl(intersectionElementAccess.ts, 4, 3)) | ||
>numberObject : Symbol(numberObject, Decl(intersectionElementAccess.ts, 0, 3)) | ||
|
||
let b = object[stringObject]; | ||
>b : Symbol(b, Decl(intersectionElementAccess.ts, 10, 3)) | ||
>object : Symbol(object, Decl(intersectionElementAccess.ts, 4, 3)) | ||
>stringObject : Symbol(stringObject, Decl(intersectionElementAccess.ts, 1, 3)) | ||
|
||
let c = object[numberString]; | ||
>c : Symbol(c, Decl(intersectionElementAccess.ts, 11, 3)) | ||
>object : Symbol(object, Decl(intersectionElementAccess.ts, 4, 3)) | ||
>numberString : Symbol(numberString, Decl(intersectionElementAccess.ts, 2, 3)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
=== tests/cases/conformance/types/intersection/intersectionElementAccess.ts === | ||
let numberObject: number & { foo: any }; | ||
>numberObject : number & { foo: any; } | ||
>foo : any | ||
|
||
let stringObject: string & { foo: any }; | ||
>stringObject : string & { foo: any; } | ||
>foo : any | ||
|
||
let numberString: number & string; | ||
>numberString : number & string | ||
|
||
let object: { | ||
>object : { [key: string]: { stringIndexer: any; }; [index: number]: { stringIndexer: any; numberIndexer: any; }; } | ||
|
||
[ index: number ]: { stringIndexer: any, numberIndexer: any }, | ||
>index : number | ||
>stringIndexer : any | ||
>numberIndexer : any | ||
|
||
[ key: string]: { stringIndexer: any } | ||
>key : string | ||
>stringIndexer : any | ||
} | ||
|
||
let a = object[numberObject]; | ||
>a : { stringIndexer: any; numberIndexer: any; } | ||
>object[numberObject] : { stringIndexer: any; numberIndexer: any; } | ||
>object : { [key: string]: { stringIndexer: any; }; [index: number]: { stringIndexer: any; numberIndexer: any; }; } | ||
>numberObject : number & { foo: any; } | ||
|
||
let b = object[stringObject]; | ||
>b : { stringIndexer: any; } | ||
>object[stringObject] : { stringIndexer: any; } | ||
>object : { [key: string]: { stringIndexer: any; }; [index: number]: { stringIndexer: any; numberIndexer: any; }; } | ||
>stringObject : string & { foo: any; } | ||
|
||
let c = object[numberString]; | ||
>c : { stringIndexer: any; numberIndexer: any; } | ||
>object[numberString] : { stringIndexer: any; numberIndexer: any; } | ||
>object : { [key: string]: { stringIndexer: any; }; [index: number]: { stringIndexer: any; numberIndexer: any; }; } | ||
>numberString : number & string | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
let numberObject: number & { foo: any }; | ||
let stringObject: string & { foo: any }; | ||
let numberString: number & string; | ||
|
||
let a = numberObject + 1; | ||
let b = stringObject + 1; | ||
let c = numberObject + ''; | ||
let d = stringObject + ''; | ||
let e = numberObject + stringObject; | ||
|
||
let f = numberString + 1; | ||
let g = numberString + ''; | ||
let h = numberString + numberString; | ||
|
||
let i = numberObject * 2; | ||
let j = numberString * 2; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
let numberObject: number & { foo: any }; | ||
let stringObject: string & { foo: any }; | ||
let numberString: number & string; | ||
|
||
let object: { | ||
[ index: number ]: { stringIndexer: any, numberIndexer: any }, | ||
[ key: string]: { stringIndexer: any } | ||
} | ||
|
||
let a = object[numberObject]; | ||
let b = object[stringObject]; | ||
let c = object[numberString]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the name of this function is now misleading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree about that, do you have a better name? Maybe just
typeHasKind
?