declare namespace XXX {
// по сути просто поле XXX.a
let a: number;
// то же поле XXX.b но уже const
// современный ts позволяет делать поля readonly, но раньше так было нельзя
const b: number;
// функция, по сути метод XXX.c()
function c(): void;
// а вот вложенный тип через тип объекта не объявить, а в namespace можно
type T = number | string;
}
declare module '*.png' {
const url: string;
export default url;
}
declare module '*.css' {
const classNames: Record<string, string>;
export default classNames;
}
let a;
t >>>= 0;
if(t < 128) a = 1;
else if(t < 16384) a = 2;
else if(t < 2097152) a = 3;
else if(t < 268435456) a = 4;
else a = 5;
this.tail.next = new f(a, t);
this.tail = this.tail.next;
this.len += this.tail.len;
return this;
Можно ли обойтись обычным js?Можно. TypeScript лишь добавляет к JavaScript статическую типизацию в компайл-тайм. После компиляции будет все тот же JS.
Какие будут плюсы?Главный плюс, ИМХО, - скорость разработки за счет подсказок IDE и автодополнения, больше авторефакторингов. Ну и возможность ограничить использование функций/методов от нежелательного использования тоже плюс. А если еще и проектировать доменную модель на типах, то можно сразу видеть, если что-то не сходится, еще до написания логики.
Не будет ли много лишней писанины по сравнению с чистым js?Большинство типов TypeScript способен вывести. Далеко не Хиндли-Милнер конечно, но тоже хорошо. Я пишу больше в ФП стиле, с редкой примесью структурно-процедурного при описании эффектов, так у меня явные указания типов присутствуют только в сигнатурах функций. В самой логике код неотличим от обычного JS, но с хорошей проверкой типов.
Будет ли сложно хранить скомпилированный js?Как и любые другие артефакты сборки, скомпилированный JS хранить не нужно. Компилируйте непосредственно перед выкладыванием на продакшен, а в git храните лишь TS код + настройки компилятора. А в dev среде вообще можно запускаться через модуль ts-node.
type Validator<U extends string, A extends ReadonlyArray<string>> =
(U extends A[number] ? true : false) extends true ? A : never;
type U = 'foo' | 'bar';
const arr0 = ['foo'] as const;
const arr1 = ['bar'] as const;
const arr2 = ['foo', 'bar'] as const;
type A0 = Validator<U, typeof arr0>; // never
type A1 = Validator<U, typeof arr1>; // never
type A2 = Validator<U, typeof arr2>; // readonly ['foo', 'bar']
const _check0: A0 = arr0; // error
const _check1: A1 = arr1; // error
const _check2: A2 = arr2;
async function checkUser(login, password) {
const ad = new ActiveDirectory(ad_config)
const auth = await new Promise((resolve, reject) => {
ad.authenticate(login, password, (err, auth) => {
if (err) {
return reject(err)
}
resolve(auth)
})
})
return auth
}
const elementSettings = {
welcome: {
placeholder: 'Type welcome message...',
question: '',
isDescription: false,
description: '',
startButtonText: 'Start',
},
checkbox: {
placeholder: 'Type question or statement...',
question: '',
isDescription: false,
description: '',
options: [] as string[],
multiple: false,
},
dropdown: {
placeholder: 'Type question here...',
question: '',
isDescription: false,
description: '',
options: [] as string[],
},
rating: {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
steps: 10,
defaultRate: 0,
shape: 'stars',
},
text: {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
maxLength: 99999,
},
slider: {
placeholder: 'Type question...',
question: '',
isDescription: false,
description: '',
steps: 10,
},
thanks: {
placeholder: 'Type message...',
question: '',
isDescription: false,
description: '',
}
} as const;
type Editable<T> = { -readonly [P in keyof T]: T[P]; };
type ElementSettings = typeof elementSettings;
export function getElementSettings<T extends keyof ElementSettings>(type: T): Editable<ElementSettings[T]> {
if(type in elementSettings) {
const settings = {...elementSettings[type]};
if('options' in settings) {
(settings as {options: string[]}).options = (settings as {options: string[]}).options.slice();
}
return settings;
}
throw new Error("element type doesn't match!");
}
mport React from 'react';
import { render } from 'react-dom';
type ITableColumn<D extends Record<string, any>> = {
property: string;
format?: (value: any, item: D) => React.ReactNode | string | number;
header?: any;
footer?: any;
};
type ITable<T extends Record<string, any>, D extends Record<string, any>> = {
isLoading?: boolean;
columns: ITableColumn<D>[];
rows: Array<T>;
};
type IContext<D extends Record<string, any>> = {
rows: any;
columns: ITableColumn<D>[];
};
const getColumns = <D extends Record<string, any>>(): ITableColumn<D>[] => [
{
property: 'name',
format: (value, item) => {
const { lastName } = item;
return `${value} ${lastName}`;
},
header: 'heade',
footer: 'footer'
},
{
property: 'count',
header: 'heade',
footer: 'footer'
}
]
interface AppProps { }
interface AppState {
name: string;
}
const Table:React.FC<ITable> = ({ isLoading, columns, rows }) => {
return <h1>table</h1>
}
const App = () => (
<div>
<Table
columns={getColumns()}
rows={[
{ name: 'userName 0', lastName: 'userLastName 0', count: 10 },
{ name: 'userName 1', lastName: 'userLastName 1', count: 20 },
{ name: 'userName 2', lastName: 'userLastName 2', count: 30 },
]}
/>
<p>Start editing to see some magic happen :)</p>
</div>
);
render(<App />, document.getElementById('root'));
import type {ComponentType} from 'react';
import {Button} from 'react-native';
type InferProps<Component> = Component extends ComponentType<infer Props> ? Props : never;
const MyButton = (props: InferProps<typeof Button>) => {
return <Button title={props.title} onPress={props.onPress} style={{color:'#fff'}} />
}
Подойдет ли тут многопоточность или я что то путаю?В JS нет многопоточности.
Как это реализовать? С помощью чего?Просто отправить несколько запросов сразу. Запросы работают асинхронно и не блокируют поток выполнения.
struct android_app *
- это возвращаемый функцией тип;(void)
после имени означает, что функция без аргументов, современные компиляторы позволяют писать просто пустые скобки ()
;// описание структуры android_app должно быть выше заголовка его использующего,
// иначе он будет невалидным. А вот описание полей (реализация) может быть и ниже
struct android_app;
struct android_app* GetAndroidApp();
комментарии говорится что я могу добавить его в HeaderЭто значит, что данные сигнатуры можно вынести в заголовочный файл (тот что с расширением .h), это позволит вставить его во множество исходников через директиву препроцессора #include
routes.map((route: IPrivateRoute | IRoute) => route.access // Здесь ошибка, так как в IRoute нет поля access, а значит нет и в юнионе IPrivateRoute | IRoute
? <PrivateRoute key={route.path} {...route}/> // а здесь, так как route.access не является тайп-гвардом, и не смотря на условие, тип по прежнему IPrivateRoute | IRoute