() => void
является потомком типа (param: any) => void
, а значит Ваш предикат в типе A становится истинным и уходит в ветку, где Вы возвращаете R из infer, который выводится к вершине иерархии - типу unknowntype A<T> = T extends (...param: infer P) => void
? P extends [infer R, ...unknown[]]
? R
: string
: string;
export const TypographyType = {
[TypographyTypeStyle.h1]: 'h1',
[TypographyTypeStyle.h2]: 'h2',
[TypographyTypeStyle.h3]: 'h3',
[TypographyTypeStyle.h4]: 'h4',
[TypographyTypeStyle.p1]: 'p',
[TypographyTypeStyle.p2]: 'p',
} as const;
type TestResult<T extends string[] | CustomClass[]> = T extends CustomClass[] ? T : void;
function test<T extends string[] | CustomClass[]>(data: T): TestResult<T> {
if (data[0] instanceof CustomClass) {
return data as TestResult<T>;
}
return undefined as TestResult<T>;
}
'get' | 'set'
), методы (функциональный тип на инстансе) и static методы (функциональный тип на самом классе).declare class ViewHack {
getPosOnScale(currentPos: number): number;
}
describe('some method', () => {
test('should return smth', () => {
const view = new View('range-slider', settings);
jest.spyOn(view as unknown as ViewHack, 'getPosOnScale').mockReturnValue(100);
});
});
class Bar<T extends Foo> {
someField: T; // это поле может быть A, B и обязано произойти от Foo
}
interface Baz<T extends Foo> {
someField: T;
}
Я ищу способ однозначно ограничить по предку на уровне типа
declare const hint: unique symbol;
class Foo {
protected [hint]: never;
}
interface IFoo extends Foo {}
class A extends Foo implements IFoo {}
class B { }
interface Baz {
someField: IFoo;
}
const a: Baz = {
someField: new A(), // нет ошибки
};
const b: Baz = {
someField: new B(), // ошибка
};
https://www.typescriptlang.org/play?jsx=0#code/CYU... какой смысл в TypeScript если писать везде any?storesFeed: any; constructor(event: any,type: any){
[string, string, string[]][]
function call<R>(f: () => R): R {
return f()
}
type Value<T> = (() => T) | T
function isFunctionValue<T>(value: Value<T>): value is () => T {
return typeof value === 'function'
}
function funcStr(value: Value<string>): string {
return isFunctionValue(value) ? value() : value
}
function funcTpl<T>(value: Value<T>): T {
return isFunctionValue(value) ? value() : value
}
type Value<T> = T extends (...args: never[]) => unknown ? never : (() => T) | T
function funcStr(value: Value<string>): string {
return typeof value === 'function' ? value() : value
}
function funcTpl<T>(value: Value<T>): T {
return typeof value === 'function' ? value() : value
}
function logDecorator<R, Args extends unknown[], This = void>(
f: (this: This, ...args: Args) => R
): (this: This, ...args: Args) => R {
return function(...args) {
console.log(f.name, this, args);
const result = f.apply(this, args);
console.log(f.name, result);
return result;
}
}
type Test = {
srn: number;
qre?: unknown;
};
const test: Test = { srn: 123 };
(['srn', 'qre'] as const).forEach((p) => {
if (typeof test[p] === 'number') {
test[p] = 34;
}
});
type Test = {
srn: number
}
const test: Test = { srn: 123 };
['srn', 'qre'].forEach((p) => {
if (p === 'srn') {
test[p] = 34;
}
});
type Test = {
srn: number
}
const test: Test = { srn: 123 };
const isKeyofTest = (s: string): s is keyof Test =>
s === 'srn';
['srn', 'qre'].forEach((p) => {
if (isKeyofTest(p)) {
test[p] = 34;
}
});
import 'firebase'; // нужно, чтоб не перетирать модуль, а мержить
declare module 'firebase' {
namespace firebase {
export const getCurrentUser: () => Promise<User>; // User тоже надо заимпортить
}
}
const obj: Record<string, string[]> = {
field1: [],
field2: [],
somefield: ['one'],
};