if (instance instanceof Animal) { ... }
, как иначе то? Как-то ты же сейчас проверяешь какой метод вызвать specificAnimalMethod
или specificHumanMethod
? export type NavDataItem =
| {
type: 'a',
name: string;
link: string;
}
| {
type: 'b',
name: string;
children: NavDataItem[];
};
json
, лучше тыкнуть в консоли на ответе "Copy object" и вставь в любой конвертер, который гуглится по "json to ts", например https://app.quicktype.io/. Так ты точно не ошибёшься, а потом уже можешь уточнить тип руками. unknown
и прогонять через тайпгард, проверяя руками, что он соответствует типу, но это не частая практика, увы. export interface Post {
title: string;
content: Content[]; // мы ждём тут массив, а не кортеж из одного элемента
}
export type TContentType = "text" | "video" | "header" | "code" | "images" | "remark" | "materials";
// базовый интерфейс, чисто для надёжности, никуда не экспортируем
interface IContentBase {
type: TContentType
}
export interface ITextContent extends IContentBase {
type: "text";
value: string;
}
export interface IVideoContent extends IContentBase {
type: "video";
url: string;
}
// ...
export interface IOtherContent extends IContentBase {
type: "header" | "code" | "images" | "remark" | "materials";
}
// делаем union с type как discriminator field
export type Content = ITextContent | IVideoContent | IOtherContent;
const items: Post = {
title: "foo bar",
content: [
{type: "text", value: "lorem 1"},
{type: "video", url: "lorem 2"},
{type: "text", value: "lorem 3"}
// ...
]
};
// используем тайпгард, тайпскрипт недостаточно умный, чтоб вывести Extract<Content, { type: "text" }> в таких случаях
const onlyTextType: ITextContent[] = items.content.filter((it): it is ITextContent => it.type === "text");
// ...
<script>
php файл который сгенерирует простой скрипт устанавливавший заданные константы и в js, условно так: header("Content-Type: application/x-javascript");
define("CONSTANT", 1);
echo 'Object.assign(window,' . json_encode(
get_defined_constants(true)['user']
) . ');';
declare const a: {a: 1, b: 2} | {a: 1};
if ('b' in a) { // ts тут сужает тип до {a: 1, b: 2}
console.log(a.b);
}
unknown
, и работа с ним исходя из этого, со всеми требуемыми проверками перед какими-либо действиями. UserInfo
обратно совместим с BaseUserInfo
, т.к. для BaseUserInfo.getState()
возвращаемое значение имеет тип void
(не путать с undefined
), который никак не может быть использован (сам ts не даст).abstract class BaseUserInfo {
abstract getState(): void;
}
class UserInfo extends BaseUserInfo {
override getState = (): number => 1;
}
function useInfo(info: BaseUserInfo) {
// An expression of type 'void' cannot be tested for truthiness.(1345)
if (info.getState()) { // не получится так сделать и всё сломать
console.log('never')
}
}
// какая-то проверка достаточная чтобы сказать, что у нас тут NextPageContext;
const isNextPageContext = (ctx: unknown): ctx is NextPageContext => false;
// аналогично для AppContext
const isAppContext = (ctx: unknown): ctx is AppContext => false;
const baseQuery = fetchBaseQuery({
baseUrl: 'http://localhost:7777/api/auth',
prepareHeaders: (headers, { extra }) => {
let req;
if (isNextPageContext(extra)) {
req = extra.req;
} else if (isAppContext(extra)) {
req = extra.ctx?.req;
}
if (req) {
headers.set('Cookie', req.headers.cookie || '');
}
return headers;
},
credentials: 'include',
});
interface CreateConnectionOptions extends ConnectOptions {
retryCount?: number;
retryDelay?: number;
}
function createConnection(uri: string, {
retryCount = 6,
retryDelay = 1000,
...mongooseConnectOptions
}: CreateConnectionOptions = {}): Observable<Connection> {
let connection$ = defer(() => mongoose.createConnection(uri, mongooseConnectOptions).asPromise());
if (retryCount > 0) {
connection$ = connection$.pipe(retry({
count: retryCount,
delay: retryDelay
}));
}
return connection$.pipe(shareReplay(1));
}
const obj = { ... };
type Obj = typeof obj;
view
кроме labled
? Props
, можно предположить, что это какие-то props какого-то React компонента, тогда этого можно добиться с помощью перегрузки:export interface ModalProps extends CuiModalProps {
children: ReactElement | ReactElement[]
setterClosePopup: Dispatch<SetStateAction<boolean>>
namePopup?: string
isOpen?: boolean
withBorder?: boolean
className?: string
}
export interface ModalPropsLabled extends ModalProps {
view: 'labeled'
label: string
}
export const Component: ((pros: ModalProps) => ReactNode) & ((pros: ModalPropsLabled) => ReactNode) = (pros: ModalProps | ModalPropsLabled) => { ... }