不確定標題是否明確(用一句話描述這個問題并不容易),但這里有一些代碼來說明這個問題(代碼塊后有關該問題的更多詳細資訊):
type AttributeDefinition = {
name:string
type: 'string' | 'number',
}
type EntityDefinition = {
attributes: Readonly<AttributeDefinition[]>
}
export type Entity<ET extends EntityDefinition> = {
[K in ET['attributes'][number] as K['name']]:
K['type'] extends 'string' ? string :
K['type'] extends 'number' ? number :
never
}
const def1 = {
attributes: [
{name:'foo', type: 'string'},
{name:'baz', type: 'number'},
] as const
}
const def2: EntityDefinition = {
attributes: [
{name:'foo', type: 'string'},
{name:'baz', type: 'number'},
] as const
}
const entity1: Entity<typeof def1> = {
foo: 'bar',
baz: 42
}
const entity2: Entity<typeof def2> = {
foo: 'bar',
baz: 42
}
entity2所以我的問題是打字稿在我想分配'bar'給foo(和)42時拋出錯誤baz。問題是TS2322: Type 'string' is not assignable to type 'never'。
但是,此問題不會發生在entity1.
這個問題的根源似乎與def2我為其注釋EntityDefinition型別的宣告有關。我這樣做是為了讓我的 IDE 輸入提示幫助我正確宣告def2物件。
但是該物件,def1即使沒有型別注釋,稍后在創建.entity1def2entity2
我不太確定為什么它會以這種方式失敗,以及如何像我一樣注釋一個物件,def2并在以后像我一樣使用這樣的物件entity1。
謝謝!
uj5u.com熱心網友回復:
失敗的原因Entity<typeof def2>是注釋擴大了 的型別def2,導致細節丟失。的型別Entity<typeof def2>等于Entity<EntityDefinition>,其計算結果為{[x: string]: never}。
您可能可以創建一個保留資訊的泛型型別注釋,但是您必須在常量型別中指定泛型引數,這會導致重復代碼。
處理這個問題的方法是創建一個只回傳引數但對其有約束的建構式:
const mkEntityDefinition = <T extends EntityDefinition>(def: T) => def
你可以像這樣使用它:
const def3 = mkEntityDefinition({
attributes: [
{name:'foo', type: 'string'},
{name:'baz', type: 'number'},
] as const
})
export const entity3: Entity<typeof def3> = {
foo: 'bar',
baz: 42
}
它將防止錯誤:
const defBad = mkEntityDefinition({
attributes: [
{name:'foo', type: 'strrring'},
{name:'baz', type: 'number'},
] as const
})
// Error: Type '"strrring"' is not assignable to type '"string" | "number"'.
// Did you mean '"string"'?
TypeScript 游樂場
uj5u.com熱心網友回復:
在satifies進入 TS 之前,您可以使用受約束的標識函式來提供 IntelliSense 幫助,同時在編輯器中實際鍵入您的定義,同時仍然允許編譯器推斷其(更具體的)文字屬性:
TS游樂場
function createEntityDefinition <T extends EntityDefinition>(def: T): T {
return def;
}
const def2 = createEntityDefinition({
attributes: [
{name:'foo', type: 'string'},
{name:'baz', type: 'number'},
] as const,
});
const entity2: Entity<typeof def2> = {
foo: 'bar',
baz: 42,
}; // ok ??
uj5u.com熱心網友回復:
我相信即將推出解決此特定用例的功能:“滿足”運算子以確保運算式匹配某種型別(反饋重置)#47920
const def2 = {
attributes: [
{name:'foo', type: 'string'},
{name:'baz', type: 'number'},
] as const
} satisfies EntityDefinition;
它仍在開發中,但您可以在Staging Playground上查看一個作業示例
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/449558.html
上一篇:無法推送到UnionType陣列
