英文:
How to infer type from another property
问题
以下是您要翻译的代码部分:
I'm typing a basic migration utility – an object that has properties `up()` and `down()`. When committing a migration I'm saving the returned data from the `up()` function and then passing it as an argument to the `down()` function, like this:
const myMigration: Migration<number[]> = {
async up() {
return [1, 2, 3];
},
async down(data) {
data.forEach(number => console.log(number)); // 1, 2, 3
},
};
So far, I've defined the Migration type like this:
type Migration<T = void> = {
up(): Promise<T>
down(data: T): Promise<void>
}
type Migration<T = void> = {
up(): Promise<T>
down<U extends T = T>(data: U): Promise<void>
}
type Migration<T = void> = {
up(): Promise<T>
down(data: Awaited<ReturnType<Migration["up"]>>): Promise<void>
}
Desired result:
const myMigration: Migration = {
async up() {
return [1, 2, 3];
},
async down(data) {
// yay, type of data is inferred
data.forEach(number => console.log(number)); // 1, 2, 3
},
};
希望这能帮助您。如果您需要进一步的帮助,请随时告诉我。
<details>
<summary>英文:</summary>
I'm typing a basic migration utility – an object that has properties `up()` and `down()`. When committing a migration I'm saving the returned data from the `up()` function and then passing it as an argument to the `down()` function, like this:
```typescript
const myMigration: Migration<number[]> = {
async up() {
return [1, 2, 3];
},
async down(data) {
data.forEach(number => console.log(number)); // 1, 2, 3
},
};
So far, I've defined the Migration type like this:
type Migration<T = void> = {
up(): Promise<T>
down(data: T): Promise<void>
}
The current problem is that I have to explicitly define the type, but rather I would like to have the type of the down()
data argument inferred from the awaited return type of up()
.
Here are some of my failed attempts:
// doesn't work
type Migration<T = void> = {
up(): Promise<T>
down<U extends T = T>(data: U): Promise<void>
}
// doesn't infer type from the same instance
type Migration<T = void> = {
up(): Promise<T>
down(data: Awaited<ReturnType<Migration["up"]>>): Promise<void>
}
Desired result:
const myMigration: Migration = {
async up() {
return [1, 2, 3];
},
async down(data) {
// yay, type of data is inferred
data.forEach(number => console.log(number)); // 1, 2, 3
},
};
答案1
得分: 1
你可以使用一个创建函数,它可以推断类型,例如:
type Migration<T> = {
up(): Promise<T>
down(
data: Awaited<ReturnType<Migration<T>['up']>>
): Promise<void>
}
function createMigration<T>(mig: Migration<T>) {
return mig;
}
const migration = createMigration({
async up() {
return [1, 2, 3]
},
async down(data) {
data.forEach((num) => console.log(num));
}
})
英文:
you could use a create function that can infer the type, e.g.
type Migration<T> = {
up(): Promise<T>
down(
data: Awaited<ReturnType<Migration<T>['up']>>
): Promise<void>
}
function createMigration<T>(mig: Migration<T>) {
return mig;
}
const migration = createMigration({
async up() {
return [1, 2, 3]
},
async down(data) {
data.forEach((num) => console.log(num));
}
})
答案2
得分: 0
以下是翻译好的部分:
"It's seems like the only way to achieve this is using factory with generic paramert. Here's an example:
type Migration<T> = {
up(): Promise<T>;
down(data: T): Promise<void>
}
const createMigration = <T>(config: Migration<T>) => config
const myMigration = createMigration({
async up() {
return [1,2,3]
},
async down(data) {
// data is infered from the `up` method
}
})
```"
<details>
<summary>英文:</summary>
It's seems like the only way to achieve this is using factory with generic paramert. Here's an example:
type Migration<T> = {
up(): Promise<T>;
down(data: T): Promise<void>
}
const createMigration = <T,>(config: Migration<T>) => config
const myMigration = createMigration({
async up() {
return [1,2,3]
},
async down(data) {
// data is infered from the up
method
}
})
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论