2018-10-31 00:56:05 +01:00
|
|
|
// @target: esnext
|
2018-09-30 00:19:52 +02:00
|
|
|
|
|
|
|
// Cannot mix bigints and numbers
|
|
|
|
let bigInt = 1n, num = 2;
|
|
|
|
bigInt = 1n; bigInt = 2; num = 1n; num = 2;
|
|
|
|
bigInt += 1n; bigInt += 2; num += 1n; num += 2;
|
|
|
|
bigInt -= 1n; bigInt -= 2; num -= 1n; num -= 2;
|
|
|
|
bigInt *= 1n; bigInt *= 2; num *= 1n; num *= 2;
|
|
|
|
bigInt /= 1n; bigInt /= 2; num /= 1n; num /= 2;
|
|
|
|
bigInt %= 1n; bigInt %= 2; num %= 1n; num %= 2;
|
|
|
|
bigInt **= 1n; bigInt **= 2; num **= 1n; num **= 2;
|
|
|
|
bigInt <<= 1n; bigInt <<= 2; num <<= 1n; num <<= 2;
|
|
|
|
bigInt >>= 1n; bigInt >>= 2; num >>= 1n; num >>= 2;
|
|
|
|
bigInt &= 1n; bigInt &= 2; num &= 1n; num &= 2;
|
|
|
|
bigInt ^= 1n; bigInt ^= 2; num ^= 1n; num ^= 2;
|
|
|
|
bigInt |= 1n; bigInt |= 2; num |= 1n; num |= 2;
|
|
|
|
bigInt = 1n + 2n; num = 1 + 2; 1 + 2n; 1n + 2;
|
|
|
|
bigInt = 1n - 2n; num = 1 - 2; 1 - 2n; 1n - 2;
|
|
|
|
bigInt = 1n * 2n; num = 1 * 2; 1 * 2n; 1n * 2;
|
|
|
|
bigInt = 1n / 2n; num = 1 / 2; 1 / 2n; 1n / 2;
|
|
|
|
bigInt = 1n % 2n; num = 1 % 2; 1 % 2n; 1n % 2;
|
|
|
|
bigInt = 1n ** 2n; num = 1 ** 2; 1 ** 2n; 1n ** 2;
|
|
|
|
bigInt = 1n & 2n; num = 1 & 2; 1 & 2n; 1n & 2;
|
|
|
|
bigInt = 1n | 2n; num = 1 | 2; 1 | 2n; 1n | 2;
|
|
|
|
bigInt = 1n ^ 2n; num = 1 ^ 2; 1 ^ 2n; 1n ^ 2;
|
|
|
|
bigInt = 1n << 2n; num = 1 << 2; 1 << 2n; 1n << 2;
|
|
|
|
bigInt = 1n >> 2n; num = 1 >> 2; 1 >> 2n; 1n >> 2;
|
|
|
|
|
|
|
|
// Plus should still coerce to strings
|
|
|
|
let str: string;
|
|
|
|
str = "abc" + 123; str = "abc" + 123n; str = 123 + "abc"; str = 123n + "abc";
|
|
|
|
|
|
|
|
// Unary operations allowed on bigints and numbers
|
|
|
|
bigInt = bigInt++; bigInt = ++bigInt; num = num++; num = ++num;
|
|
|
|
bigInt = bigInt--; bigInt = --bigInt; num = num--; num = --num;
|
|
|
|
bigInt = -bigInt; num = -num;
|
|
|
|
bigInt = ~bigInt; num = ~num;
|
|
|
|
|
|
|
|
// Number-only operations
|
|
|
|
bigInt >>>= 1n; num >>>= 2;
|
|
|
|
bigInt = bigInt >>> 1n; num = num >>> 2;
|
|
|
|
num = +bigInt; num = +num; num = +"3";
|
|
|
|
|
|
|
|
// Comparisons can be mixed
|
|
|
|
let result: boolean;
|
|
|
|
result = bigInt > num;
|
|
|
|
result = bigInt >= num;
|
|
|
|
result = bigInt < num;
|
|
|
|
result = bigInt <= num;
|
|
|
|
|
|
|
|
// Trying to compare for equality is likely an error (since 1 == "1" is disallowed)
|
|
|
|
result = bigInt == num;
|
|
|
|
result = bigInt != num;
|
|
|
|
result = bigInt === num;
|
|
|
|
result = bigInt !== num;
|
|
|
|
|
|
|
|
// Types of arithmetic operations on other types
|
|
|
|
num = "3" & 5; num = 2 ** false; // should error, but infer number
|
|
|
|
"3" & 5n; 2n ** false; // should error, result in any
|
|
|
|
num = ~"3"; num = -false; // should infer number
|
|
|
|
let bigIntOrNumber: bigint | number;
|
|
|
|
bigIntOrNumber + bigIntOrNumber; // should error, result in any
|
|
|
|
bigIntOrNumber << bigIntOrNumber; // should error, result in any
|
|
|
|
if (typeof bigIntOrNumber === "bigint") {
|
|
|
|
// Allowed, as type is narrowed to bigint
|
|
|
|
bigIntOrNumber = bigIntOrNumber << bigIntOrNumber;
|
|
|
|
}
|
|
|
|
if (typeof bigIntOrNumber === "number") {
|
|
|
|
// Allowed, as type is narrowed to number
|
|
|
|
bigIntOrNumber = bigIntOrNumber << bigIntOrNumber;
|
|
|
|
}
|
|
|
|
+bigIntOrNumber; // should error, result in number
|
|
|
|
~bigIntOrNumber; // should infer number | bigint
|
|
|
|
bigIntOrNumber++; // should infer number | bigint
|
|
|
|
++bigIntOrNumber; // should infer number | bigint
|
|
|
|
let anyValue: any;
|
|
|
|
anyValue + anyValue; // should infer any
|
|
|
|
anyValue >>> anyValue; // should infer number
|
|
|
|
anyValue ^ anyValue; // should infer number
|
|
|
|
+anyValue; // should infer number
|
|
|
|
-anyValue; // should infer number
|
|
|
|
anyValue--; // should infer number
|
|
|
|
--anyValue; // should infer number
|
|
|
|
|
|
|
|
// Distinguishing numbers from bigints with typeof
|
|
|
|
const isBigInt: (x: 0n | 1n) => bigint = (x: 0n | 1n) => x;
|
|
|
|
const isNumber: (x: 0 | 1) => number = (x: 0 | 1) => x;
|
|
|
|
const zeroOrBigOne: 0 | 1n;
|
|
|
|
if (typeof zeroOrBigOne === "bigint") isBigInt(zeroOrBigOne);
|
|
|
|
else isNumber(zeroOrBigOne);
|
|
|
|
|
|
|
|
// Distinguishing truthy from falsy
|
|
|
|
const isOne = (x: 1 | 1n) => x;
|
|
|
|
if (zeroOrBigOne) isOne(zeroOrBigOne);
|
|
|
|
const bigZeroOrOne: 0n | 1;
|
|
|
|
if (bigZeroOrOne) isOne(bigZeroOrOne);
|