유형 스크립트의 정적 메서드에서 클래스 유형 인수에 액세스하기 위한 해결 방법
다음 오류
정적 멤버는 클래스 유형 매개 변수를 참조할 수 없습니다.
다음 코드 조각의 결과
abstract class Resource<T> {
/* static methods */
public static list: T[] = [];
public async static fetch(): Promise<T[]> {
this.list = await service.get();
return this.list;
}
/* instance methods */
public save(): Promise<T> {
return service.post(this);
}
}
class Model extends Resource<Model> {
}
/* this is what I would like, but the because is not allowed because :
"Static members cannot reference class type parameters."
*/
const modelList = await Model.fetch() // inferred type would be Model[]
const availableInstances = Model.list // inferred type would be Model[]
const savedInstance = modelInstance.save() // inferred type would be Model
저는 이 사례를 통해 제가 성취하고자 하는 것이 무엇인지 분명하다고 생각합니다.상속 클래스에서 인스턴스와 정적 메서드를 호출하고 상속 클래스 자체를 유추 유형으로 지정할 수 있기를 원합니다.원하는 것을 얻기 위한 해결 방법은 다음과 같습니다.
interface Instantiable<T> {
new (...args: any[]): T;
}
interface ResourceType<T> extends Instantiable<T> {
list<U extends Resource>(this: ResourceType<U>): U[];
fetch<U extends Resource>(this: ResourceType<U>): Promise<U[]>;
}
const instanceLists: any = {} // some object that stores list with constructor.name as key
abstract class Resource {
/* static methods */
public static list<T extends Resource>(this: ResourceType<T>): T[] {
const constructorName = this.name;
return instanceLists[constructorName] // abusing any here, but it works :(
}
public async static fetch<T extends Resource>(this: ResourceType<T>): Promise<T[]> {
const result = await service.get()
store(result, instanceLists) // some fn that puts it in instanceLists
return result;
}
/* instance methods */
public save(): Promise<this> {
return service.post(this);
}
}
class Model extends Resource {
}
/* now inferred types are correct */
const modelList = await Model.fetch()
const availableInstances = Model.list
const savedInstance = modelInstance.save()
제가 가진 문제는 정적 방법을 무시하는 것이 정말 지루해진다는 것입니다.다음을 수행합니다.
class Model extends Resource {
public async static fetch(): Promise<Model[]> {
return super.fetch();
}
}
다음과 같은 이유로 오류가 발생합니다.Model
더 이상 확장되지 않음Resource
정확하게, 다른 서명 때문에.오류를 주지 않고 페치 메소드를 선언할 수 있는 방법은 생각할 수 없고, 쉽게 오버로드할 수 있는 직관적인 방법은 말할 것도대체로 없습니다.
제가 일할 수 있었던 유일한 일은 다음과 같습니다.
class Model extends Resource {
public async static get(): Promise<Model[]> {
return super.fetch({ url: 'custom-url?query=params' }) as Promise<Model[]>;
}
}
제 생각에는, 이것은 별로 좋지 않습니다.
모델에 수동으로 캐스트하고 제네릭으로 트릭을 하지 않고 페치 방법을 재정의할 수 있는 방법이 있습니까?
다음과 같은 작업을 수행할 수 있습니다.
function Resource<T>() {
abstract class Resource {
/* static methods */
public static list: T[] = [];
public static async fetch(): Promise<T[]> {
return null!;
}
/* instance methods */
public save(): Promise<T> {
return null!
}
}
return Resource;
}
위에서Resource
로컬로 선언된 클래스를 반환하는 일반 함수입니다.반환된 클래스는 제네릭이 아니므로 정적 속성 및 메서드는 다음에 대한 구체적인 유형을 가집니다.T
다음과 같이 확장할 수 있습니다.
class Model extends Resource<Model>() {
// overloading should also work
public static async fetch(): Promise<Model[]> {
return super.fetch();
}
}
모든 것에는 다음과 같은 유형이 있습니다.
Model.list; // Model[]
Model.fetch(); // Promise<Model[]>
new Model().save(); // Promise<Model>
그래서 그게 당신에게 효과가 있을지도 모릅니다.
지금 내가 볼 수 있는 유일한 경고는:
에 약간의 중복이 있습니다.
class X extends Resource<X>()
완벽하지는 않지만 두 번째를 허용하는 상황별 타이핑을 할 수는 없다고 생각합니다.X
짐작하건대로컬로 선언된 유형은 내보낼 수 없거나 선언으로 사용되지 않는 경향이 있으므로 주의하거나 해결 방법을 마련해야 할 수 있습니다(예: 구조적으로 동일하거나 구조적으로 충분히 가까운 유형을 내보내고 다음과 같이 선언합니다).
Resource
그런 유형입니까?).
어쨌든 도움이 되길 바랍니다.행운을 빕니다.
언급URL : https://stackoverflow.com/questions/52518125/workaround-for-accessing-class-type-arguments-in-static-method-in-typescript
'programing' 카테고리의 다른 글
3항 연산자가 R에 존재합니까? (0) | 2023.06.20 |
---|---|
SpringBoot 1.4에서 SpringMVC 슬라이스 테스트 문제 (0) | 2023.06.20 |
클릭 후 VBA Excel 버튼 크기 조정(명령 버튼) (0) | 2023.06.20 |
파이썬 루프의 'else' 절을 어떻게 이해할 수 있습니까? (0) | 2023.06.20 |
pyspark 데이터 프레임에 고유한 열 값 표시 (0) | 2023.06.20 |