是否可以像在打字稿中那样使用'this'关键字声明类型?



示例:

// ===== Declaration ===== //
class A {
CONSTS_TYPE: { [key: string]: [any] }
CONSTS: { [key in keyof this['CONSTS_TYPE']]: key }
foo<T extends keyof this['CONSTS_TYPE'] | string>(
type: T,
callback: (...args: T extends keyof this['CONSTS_TYPE'] ? this['CONSTS_TYPE'][T] : any) => any
) { /** some implementation*/ }
}
class B extends A {
CONSTS_TYPE: {
aa: [number],
bb: [string]
}
// Here is the problem
// Type '{ aa: "aa"; bb: "bb"; }' is not assignable to type '{ [key in keyof this["CONSTS_TYPE"]]: key; }'.(2322)
CONSTS: { [key in keyof this['CONSTS_TYPE']]: key } = {
aa: 'aa',
bb: 'bb'
}
}
// ===== Call ===== //
const b = new B;
b.foo(b.CONSTS.aa, (arg) => {
// so that i can know 'arg' is a 'number' type
arg // number type
});

效果很好,但不是太好。

我知道"//@ts-忽略"会很好地工作

但我认为可能还有其他解决方案

[游乐场链接]

所以,我认为你的代码存在一些问题:

  • 您应该尽可能避免使用@ts-ignore
  • aa: 'aa',不是一个数字,应该给你一个错误。它不是导致您实现它的方式的原因
  • ...args: T中,T是一个数组,而不是你想象的一个参数
  • 为什么在foo中使用...args

以下是我认为可以解决您的问题:

// ===== Declaration ===== //
type ValueOf<T> = T[keyof T];
abstract class A {
abstract CONSTS: { [key: string]: any }
foo<T extends ValueOf<this['CONSTS']>>(
type: T,
callback: (arg: T) => any
) { /** some implementation*/ }
}
class B extends A {
CONSTS: {
aa: number,
bb: string
} = {
aa: 5,
bb: 'bb'
}
}
// ===== Call ===== //
const b = new B;
b.foo(b.CONSTS.bb, (arg) => {
// so that i can know 'arg' is a 'string' type
arg // string type
});

打字稿游乐场

泛型类不是您真正要找的吗?

declare class Foo<T extends Record<string, [any]>> {
CONST_TYPES: T;
CONSTS: {
[K in keyof T]: K
}
constructor(types: T);
foo<U extends keyof T>(type: U, callback: (value: T[U]) => any): any;
}
const foo = new Foo({ aa: [42], bb: ['foo'] });
foo.foo(foo.CONSTS.bb, (arg) => {
arg // [string]
})

终于我找到了解决方案

// ===== Declaration ===== //
class A<T extends Record<string, [any?]>> {
foo<U extends keyof T | string>(
type: U,
callback: (...args: U extends keyof T ? T[U] : any) => any
) { /** some implementation*/ }
}
type T_BConstsType = {
aa: [number],
bb: [string]
}
class B extends A<T_BConstsType> {
CONSTS: { [key in keyof T_BConstsType]: key } = {
aa: 'aa',
bb: 'bb'
}
}
// ===== Call ===== //
const b = new B;
b.foo(b.CONSTS.aa, (arg) => {
// so that i can know 'arg' is a 'number' type
arg // number type
});

操场

相关内容

最新更新