부분적으로 (JavaScript에서) TypeScript로 변환 된 다음 코드가 있습니다.
기본적으로 callback
매개 변수가 있으면 항상 함수 자체가 void
. 그렇지 않으면 type을 반환합니다 Promise<object>
. 그 settings
전에 선택적 매개 변수 ( )를 사용합니다 (기술적으로 callback
매개 변수 는 매개 변수로 전달 될 수 있으며 settings
함수의 처음 몇 줄이 해당 사용 사례를 처리합니다).
이전 버전과의 호환성을 위해 (그리고 코드를 DRY로 유지하기 위해) savePromise
or 라는 다른 함수를 만들고 saveCallback
분리 하고 싶지 않습니다 . 나는 TypeScript가 어떻게 든이 논리를 이해할만큼 똑똑하게 만드는 방법을 알아 내려고 노력하고 있습니다.
type CallbackType<T, E> = (response: T | null, error?: E) => void;
class User {
save(data: string, settings?: object, callback?: CallbackType<object, string>): Promise<object> | void {
if (typeof settings === "function") {
callback = settings;
settings = undefined;
}
if (callback) {
setTimeout(() => {
callback({"id": 1, "settings": settings});
}, 1000);
} else {
return new Promise((resolve) => {
setTimeout(() => {
resolve({"id": 1, "settings": settings});
}, 1000);
});
}
}
}
const a = new User().save("Hello World"); // Should be type Promise<object>, should eventually resolve to {"id": 1, "settings": undefined}
const b = new User().save("Hello World", (obj) => {
console.log(obj); // {"id": 1, "settings": undefined}
}); // Should be type void
const c = new User().save("Hello World", {"log": true}); // Should be type Promise<object>, should eventually resolve to {"id": 1, "settings": {"log": true}}
const d = new User().save("Hello World", {"log": true}, (obj) => {
console.log(obj); // {"id": 1, "settings": {"log": true}}
}); // Should be type void
내가 목표로하는 유형 파일이 다음과 같은 내용이 될 것이라고 확신합니다. 내가 여기서 정확한지 확실하지 않습니다.
save(data: string, settings?: object): Promise<object>;
save(data: string, callback: CallbackType<object, string>): void;
save(data: string, settings: object, callback: CallbackType<object, string>): void;
매개 변수 사용 사례 callback
로 전달 되는 매개 변수는 settings
다음과 같은 작업을 수행하여 처리 할 수 있습니다.
save(data: string, settings?: object | CallbackType<object, string>, callback?: CallbackType<object, string>): Promise<object> | void
그러나 그것은 매우 지저분하고 내 경험상 TypeScript가 settings
함수의 처음 4 줄의 코드 이후에 항상 선택적 객체가 될 것이라는 것을 깨닫기에 충분히 똑똑한 것 같지 않습니다 . 즉, 전화 callback
할 때 캐스트를 입력해야합니다. 다시 말하면 정말 지저분하게 느껴집니다.
TypeScript로 어떻게 이것을 달성 할 수 있습니까?
해결책은 다음과 같습니다 (일부 리팩토링 포함).
type CallbackType<T, E> = (response: T | null, error?: E) => void;
interface ISettings {
log?: boolean;
}
interface ISaveResult {
id: number;
settings: ISettings | undefined;
}
class User {
save(data: string): Promise<ISaveResult>;
save(data: string, settings: ISettings): Promise<ISaveResult>;
save(data: string, callback: CallbackType<ISaveResult, string>): void;
save(data: string, settings: ISettings, callback: CallbackType<ISaveResult, string>): void;
save(data: string, settings?: ISettings | CallbackType<ISaveResult, string>, callback?: CallbackType<ISaveResult, string>): Promise<ISaveResult> | void {
if (typeof settings !== "object" && typeof settings !== "undefined") {
callback = settings;
settings = undefined;
}
const localSettings = settings; // required for closure compatibility
if (callback) {
const localCallback = callback; // required for closure compatibility
setTimeout(() => {
localCallback({ id: 1, "settings": localSettings });
}, 1000);
} else {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ id: 1, "settings": localSettings });
}, 1000);
});
}
}
}
const a = new User().save("Hello World"); // User.save(data: string): Promise<ISaveResult>
const b = new User().save("Hello World", obj => {
console.log(obj); // obj: ISaveResult | null
}); // User.save(data: string, callback: CallbackType<ISaveResult, string>): void
const c = new User().save("Hello World", { "log": true }); // User.save(data: string, settings: ISettings): Promise<ISaveResult>
const d = new User().save("Hello World", { "log": true }, (obj) => {
console.log(obj); // obj: ISaveResult | null
}); // User.save(data: string, settings: ISettings, callback: CallbackType<ISaveResult, string>): void
코드 팬 참조
a는 Function
입니다 Object
타이프는 암시 적으로 두 가지를 구별 할 수 없습니다, 그래서뿐만 아니라. 특정 ISettings
인터페이스 를 만들면 TypeScript가 설정 개체와 콜백 함수를 구분할 수 있습니다.
이를 확인하는 가장 쉬운 방법은 TypeScript가 내놓은 오류와 코드 흐름이 진행됨에 따라 변수의 유형을 살펴 보는 것입니다. 예 : ( your code ) :
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다