getFormattedData
тоже должен быть дженерик и собсно его(дженерик) прокидывать в нижестоящие.type Type1 = 1;
type Type2 = 2;
type Type3 = 3;
type ContainsType<T extends UniversalType = UniversalType> = {type: T};
type UniversalType = Type1 | Type2 | Type3;
class Cls {
async getFormattedData<T extends UniversalType>(data: ContainsType<T>): Promise<T> {
const anyDataObject = this.validateData(data);
const result = this.formatDataByType(anyDataObject);
return result;
}
validateData<T extends UniversalType = UniversalType>(data: ContainsType<T>): T {
return data.type
}
formatDataByType<T extends UniversalType = UniversalType>(data: T): T {
return data
}
}
const foo = await new Cls().getFormattedData({type: 2}); // 2
const anyDataObject: Type1 | Type2 | Type3 = ...
if (anyDataObject === 2) {
// тут anyDataObject для ts считается Type2
}
но это уже никак не повлияет на выходной тип.Math.random()
. interface MutableRefObject<T> {
prev: null | HTMLParagraphElement;
}
declare module 'lib-name' {
interface MutableRefObject<T> {
prev: null | HTMLParagraphElement;
}
}
declare module 'lib-name/full/path/to/declaration.ts' {
interface MutableRefObject<T> {
prev: null | HTMLParagraphElement;
}
}
interface MySuperMutableRefObject extends MutableRefObject<T> {
prev?: null | HTMLParagraphElement;
}
if (error.value?.statusCode !== 404)
не гарантирует, что в user
не будет null
, мало ли там ошибка 50х
или даже нет ошибки, а просто сервер глюканул.if (!user) {
throw new Error('empty responce')
}
useFetch
которая внутри себя скастует тип по новому или изменение самого типа useFetch
. const result = (blogPosts as Posts)[props.name]
blogPosts
- нужного типа:// тайпргард: тут проверка что posts действительно Posts;
const isPosts = (posts: unknown): posts is Posts => !!posts
&& typeof posts === 'object'
//&& ... ;
if (!isPosts(blogPosts)) throw new Error('wrong blogPosts');
const result = blogPosts[props.name];
class A { id!: string }
class B { id!: string }
class C {
id!: string;
value!: number;
}
const foo: A = new B(); // ok
const bar: A = new C(); // still ok
unknown
. Функции проверки что неизвестный тип является конкретным называются тайпгарды: function isString(arg: unknown): arg is string {
return typeof arg === 'syting'
}
const ThemeProvider: FC = ...;
ThemeProvider
имеет тип FC
, и пофиг что ты там дальше пишешь. Тип FC
по умолчанию не имеет children
.const ThemeProvider: FC<{children: ...}> = ...;
const ThemeProvider = ({ children }: ...) => ...;
props
, children
это поле props
, а не верхний аргумент.const ThemeProvider: FC<PropsWithChildren> = ...
PropsWithChildren
- тип помощник, добавляющий children
к объекту, например PropsWithChildren<{
prop2: string;
prop3: number
}>
но без дженерика просто отдаёт тип вида {
children?: ReactNode | undefined;
}
type Lettrer = 'a' | 'b' | ...
type Digit = 1 | 2 | ...
...
string
и просто number
.type ZipCode = string;
type GeoCoord = number;
type
:type BaseColumn = { label: string; props: string }
type Column = { type: 'text' } & BaseColumn
type LinkColumn = { type: 'link'; path: string } & BaseColumn
type TableColumn = Column | LinkColumn
keyof
для юниона объектов показывает только те поля, которые есть в каждом из них. Это логично, т.к. к типу TableColumn
ты не можешь обратиться по полую .link
предварительно не сузив тип. union
- строгий. .push
и тебе откроет файл с декларацией, если она не\не только в next/dist/shared/lib/app-router-context.d.ts
- разбирайся откуда взялась левая.