typescript 如何让TypesScript嵌套类型推断停止给出虚假的类型错误

6tr1vspr  于 6个月前  发布在  TypeScript
关注(0)|答案(1)|浏览(87)

我有一个类型(通过在对象上使用typeof创建),它描述了我的数据库:

type DATABASE_METADATA = typeof databaseMetadata;
let databaseMetadata = {
    "management": {
        "databaseName": "management",
        "public": {
            "schemaName": "public",
            "tables": {
                "secrets": {
                    "example_type": null as any as { x: number },
                },
            }
        }
    }
};

字符串
我为一个函数写了类型,这个函数最终将向数据库中插入一个值,使用我的数据库类型来确保我的数据库,模式,表和值都是类型检查的:

function createAndInsertSql2<DatabaseName extends keyof DATABASE_METADATA>(
    databaseName: DatabaseName
) {
    type Database = DATABASE_METADATA[DatabaseName];
    return function<SchemaName extends keyof Database>(
        schemaName: SchemaName
    ) {
        type Schema = Database[SchemaName];
        return function <TableName extends keyof Schema["tables"])> (
            tableName: TableName,
            value: Schema["tables"][TableName]["example_type"],
        ) {
            // Insert value into database with name databaseName, schema schemaName and table tableName.
        };
    };
}


但是,这会产生类型错误,从Schema["tables"]开始,错误是:Type '"tables"' cannot be used to index type 'Schema'.(2536)
这是特别恼人的,因为使用的功能实际上类型检查正确,所以Typescript是推断什么类型我想要的.它只是认为它不能?

// Does not give a type error
createAndInsertSql2("management")("public")("secrets", { x: 5 });

// Gives a type error
createAndInsertSql2("management")("public")("secrets", { });


如何更改函数定义以删除类型错误,同时仍然推断和类型检查example_type的类型?

qgzx9mmu

qgzx9mmu1#

@jcalz的评论让我走上了正确的道路(我没有足够地约束SchemaName,所以它可能是实际上会破坏函数的值)。弄清楚这一点有助于我写一些有用的东西。我将保留这个问题,以防其他人有不同的方法。

type DATABASE_METADATA = typeof databaseMetadata;
let databaseMetadata = {
    "management": {
        "databaseName": "management",    
        "public": {
            "schemaName": "public",
            "tables": {
                "secrets": {
                    "example_type": null as any as { x: number },
                },
            }
        }
    }
};

export async function createAndInsertSql<
    DatabaseName extends keyof DATABASE_METADATA,
    Database extends DATABASE_METADATA[DatabaseName],
    SchemaName extends keyof Database,
    SchemaType extends Database[SchemaName] & { tables: unknown },
    TableName extends keyof SchemaType["tables"],
    TableType extends SchemaType["tables"][TableName] & { example_type: unknown },
    ValueType extends TableType["example_type"]
>(
    databaseName: DatabaseName,
    schemaName: SchemaName & string,
    tableName: TableName & string,
    value: ValueType,
) {
    // Insert value into databaseName, under schemaName, in tableName
}

// Does not give a type error
createAndInsertSql("management", "public", "secrets", { x: 5 });

// Gives a type error
createAndInsertSql("management", "public", "secrets", { });

字符串

相关问题