import { FC } from "react";
type WithName = { name: string };
type WithPath = { path: string };
type WithStateProps = { tabs: WithName[] };
type WithRouterProps = { withRouter: true; baseUrl?: string; tabs: WithPath[]; };
const TabsWithRouter: FC = (props) => null; const TabsWithState: FC = (props) => null;
type TabsProps = WithStateProps | WithRouterProps;
const Tabs = (props: TabsProps) => { if (props.withRouter) { // error return <TabsWithRouter {...props} />; // error } return <TabsWithState {...props} />; // error };
const Test = () => (
const enum Colors {
Red = 1 << 1,
Green = 1 << 2,
Blue = 1 << 3,
Yellow = Red | Green,
Magenta = Blue | Red,
Cyan = Green | Blue,
}
const hasRed = (color: Colors) => Boolean(color & Colors.Red)
hasRed(Colors.Magenta) // true
hasRed(Colors.Cyan) // false/**
* To make it more React friendly,
* Let's assume we expect next Props:
*/
type Props = {
active: boolean,
top: boolean,
external: boolean,
optional: boolean,
}
// These props we are received
const propsA: Props = {
active: true, // first bit
top: false, // second bit
external: false, // third bit
optional: true // fourth bit
}
// This is how we can represent it
// BitMask is singleton, you don't need create it every time
const BitMask = {
active: 1 << 1,
top: 1 << 2,
external: 1 << 3,
optional: 1 << 4
} as const;
const propsA2 = BitMask.active | BitMask.optional // 00010 | 10000 => 10010
// So, instead of passing the whole object every time, we can just use one number.
// propsA and propsA2 represent same data
// So every algebraic SUM type can be represented as bit mask- Import type
- Private Fields
- Top Level Await
- JSDoc Improvements
- Watch Options
// Look at the JS, this isn't included in the output import {DangerDSLType} from "danger"Tools like Babel, which don’t type-check can be certain with 100% accuracy whether to remove the import.
declare const myDSL: DangerDSLType
myDSL.bitbucket_cloud
// On the other hand, this one is... import {danger} from "danger" danger.git
// But why?
// TS keeps track of whether an import is a "JS" value // or a TypeScript type. import {DangerDSLJSONType, message} from "danger" message
// Babel cannot do this!
// So now Babel knows that it can always skip these // 'import type' statements import type {DangerUtilsDSL} from "danger"
// Because they can't be used with "JS" values: import type {markdown} from "danger"
There are folks who want to rely on importing side-effects, but also import a type from that import
// This statement will get erased because of import elision.
import { SomeTypeFoo, SomeOtherTypeBar } from "./module-with-side-effects";
// This statement always sticks around.
import "./module-with-side-effects";/**
- Binary, Octal and Hexadecimal number representation */
/** *
- Bit mask data structure
- You can find bitmask data stuctures in TS compiler source code
- https://github.com/microsoft/TypeScript/blob/45b698b3f6679c16d69f9117bdbcd0aeb498a8c0/src/compiler/transformers/ts.ts#L17
- For example: */ const enum Colors { Red = 1 << 1, Green = 1 << 2, Blue = 1 << 3, Yellow = Red | Green, Magenta = Blue | Red, Cyan = Green | Blue, }
const hasRed = (color: Colors) => Boolean(color & Colors.Red) hasRed(Colors.Magenta) // true hasRed(Colors.Cyan) // false /**
- To make it more React friendly,
- Let's assume we expect next Props: */ type Props = { active: boolean, top: boolean, external: boolean, optional: boolean, }
// These props we are received const propsA: Props = { active: true, // first bit top: false, // second bit external: false, // third bit optional: true // fourth bit }
// This is how we can represent it // BitMask is singleton, you don't need create it every time const BitMask = { active: 1 << 1, top: 1 << 2, external: 1 << 3, optional: 1 << 4 } as const;
const propsA2 = BitMask.active | BitMask.optional // 00010 | 10000 => 10010 // So, instead of passing the whole object every time, we can just use one number. // propsA and propsA2 represent same data // So every algebraic SUM type can be represented as bit mask
/**
- And the main question is: How to opack JS regular objects into bits?
- As a frontend developer, in 99% cases I have a deal with array ob objects, not array of numbers. */ const obj = { top: true, category: 242, id: 123_456 }; // boolean and numbers, not strings
/**
- Constraints:
- So, TOP can be either 1 or 0, the easy one (T)
- no more than 999 categories (C)
- no more than 1_000_000 ID's (I) */
/**
- Let's start with IS'd encoding.
- How many bits we should allocate for ID's?
- 1_000_000..toString(2).length -> we should allocate 20 bits
- How many bits for category?
- 999..toString(2).length -> 10
- And for top? - 1 bit, because it is a boolean
- TOP: 1
- CATEGORY: 10
- ID's: 20
- Result:
- T(1)-CCCCCCCCCC(10)-IIIIIIIIIIIIIIIIIIII(20)
- TCCCCCCCCCCIIIIIIIIIIIIIIIIIIII -> length 31
*/
const id_hex = 123_456..toString(16) // 1e240 // 11110001001000000 const category_hex = 242..toString(16) // f2 // 11110010 const top_hex = 1..toString(16) // 1 const result = 0x1f21e240 // 1 - f2 - 1e240, binary representation 1 11110010 000 11110001001000000 /**
- I'd willing to bet that you are familiar whith such kind of numbers.
- It is common pattern to encode errors in this way */