In a nutshell, flat feature folders:
src/
app/
home.tsx
app-header.tsx
app-sidebar.tsx
Simplified, styled.hr is typed to accept either a template string interpolation, or a valid style object.
In this case, a valid style object is that which borderTopStyle can only be one of many possible strings, specifically, the type 'solid' | '...'
However, TS' default behavior is to infer any objects' properties as string, and string is not assignable to 'solid' | '...'.
// obj.a is type "string" not type "'hello'"
const obj = { a: 'hello' }| class Container<S> { | |
| setState(newState: Partial<S>) { | |
| // ... | |
| } | |
| } | |
| type CounterState = { | |
| count: number | |
| } |
| import useSimpleState from "./useSimpleState" | |
| type LoadingState = { | |
| status: "idle" | "loading" | "success" | "error" | |
| error?: string | |
| } | |
| export default function useLoadingState() { | |
| const [state, setState] = useSimpleState<LoadingState>({ status: "idle" }) |
| test('Emitter', () => { | |
| const emitter = new Emitter() | |
| let counter = 0 | |
| const increment = () => counter += 1 | |
| // test the handler being fired | |
| emitter.on('increment', increment) | |
| emitter.emit('increment') | |
| expect(counter).toBe(1) |
| export interface CachedResource<I extends any[], V> { | |
| load(...input: I): Promise<V> | |
| loadSuspended(...input: I): V | |
| has(...input: I): boolean | |
| get(...input: I): V | undefined | |
| set(item: V, ...input: I): void | |
| invalidate(...input: I): void | |
| clear(): void | |
| } |
| let value: string | undefined | |
| const items: any[] = [] | |
| if (value) { | |
| items.forEach(() => { | |
| // value is string | undefined | |
| // TS can't (and shouldn't) know whether this callback is synchronous; `value` might have changed | |
| value | |
| }) |
| import React, { useState } from "react" | |
| export default function InfiniteList() { | |
| // have a list of "pages" in our state | |
| const [pages, setPages] = useState([]) | |
| // the number of items we have per page | |
| const count = 20 | |
| // this function should be called whenever the user wants to "move on" in the list |
| { | |
| "compilerOptions": { | |
| /* Basic Options */ | |
| "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ | |
| "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ | |
| // "lib": ["dom", "dom.iterable", "esnext"], /* Specify library files to be included in the compilation. */ | |
| // "allowJs": true, /* Allow javascript files to be compiled. */ | |
| // "checkJs": true, /* Report errors in .js files. */ | |
| "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ | |
| // "declaration": true, /* Generates corresponding '.d.ts' file. */ |
| data here lol! |