问题描述
强类型语言很多。为啥ts会有类型体操。但是在编译后却把类型注释去掉了。那这个类型体操具体有啥用?
TypeScript 聪明反被聪明误, 处于一种微妙的位置.
类型系统比 TS 烂的, type 比 term 少太多原语, type level 压根无法表示复杂逻辑, 从未有过这种烦恼.
类型系统超越了 TS, 达到 DT 级别的, 此时 term 就是 type, type 就是 term, 也不用写两遍.
只有 TS 不上不下, 夹在中间, type 和 term 有同样能力的原语, 但是 type 和 term 却不等同
于是一模一样的逻辑 term level 写了一遍, type level 又要写一遍, 直接违背 DRY(Don't Repeat Yourself) 原则.
而且类型推倒只是一种轻量级编译期计算, 本来就不适合复杂的编译期计算.
那其他非 DT 语言里复杂场景下的类型安全一般是通过什么方式保证的?
当然是编译期强制常量计算
需求: 编译期解析 SQL 并验证输入参数的数量和类型是否符合该语句
- C++: 直接一个 constexpr 定义常量函数
sql::query搞定 - Rust: 直接一个 macro 定义函数宏
sqlx::query!搞定 - Zig: 直接一个 comptime 定义编译期过程
@query搞定
C++, Rust, Zig: Typesciprt 怎么还没搞定, 你们有什么头绪吗?
- TypeScript: 首先用类型体操写一个 Tokenize, 然后用类型体操写一个标记树撕裂机, 然后用类型体操写一个 Parser, 然后用类型体操定义 SQL AST, 然后用类型体操完成一个 SQL 解析器, 然后用类型体操验证该 SQL 的表达式是否合法, 然后用类型体操提取 SQL 中的 Arguments, 然后用类型体操验证传入的参数数量是否合法, 然后用类型体操验证传入的参数的类型是否合法. 最后用类型体操把这些东西全™写进泛型里定义为
Query<T>
export type Parse<T> =
ParseStatement<T> extends [infer Statement, infer Rest] ?
Trim<Rest> extends ';' ? Statement :
Trim<Rest> extends '' ? Statement : never :
never;
type ParseStatement<T> =
ParseSelectStatement<T> | ParseInsertStatement<T> | ParseUpdateStatement<T> | ParseDeleteStatement<T>;
type ParseSelectStatement<T> =
ParseSelectClause<T> extends Partial<SelectStatement<infer Fields, infer From, infer Joins, infer Where, infer Offset, infer Limit>>
? [SelectStatement<Fields, From, Joins, Where, Offset, Limit>, '']
: never
type ParseTableSpecifier<T> =
T extends `${infer Source} AS ${infer Alias}` ? TableSpecifier<Identifier<Source>, Identifier<Alias>> :
T extends `${infer Source} ${infer Alias}` ? TableSpecifier<Identifier<Source>, Identifier<Alias>> :
T extends string ? TableSpecifier<Identifier<Trim<T>>> :
never;
type ParseSelectClause<T>
= T extends `SELECT ${infer FieldNames} FROM ${infer R0}` ?
Merge<{fields: ParseFieldSpecifierList<FieldNames>} & ParseFromClause<Trim<R0>>>
: never;
type ParseFromClause<T> =
Tokenize<T> extends [infer Source, infer R0] ?
Tokenize<R0> extends ['AS', infer R1]
? Tokenize<R1> extends [infer Alias, infer R2]
? {from: TableSpecifier<Identifier<Source & string>, Identifier<Alias & string>>} & ParseJoinClause<R2>
: never
: {from: TableSpecifier<Identifier<Source & string>>} & ParseJoinClause<R0>
: never;
type ParseJoinClause<T> =
Trim<T> extends `INNER JOIN ${infer TableName} ON ${infer R0}`
? ParseExpression<R0> extends [infer Exp, infer R1]
? Exp extends Expression
? {joins: [InnerJoinSpecifier<ParseTableSpecifier<TableName>, Exp>]} & ParseWhereClause<Trim<R1>>
: never
: never
: ParseWhereClause<Trim<T>> & {joins: []}
type ParseWhereClause<T> =
Trim<T> extends ''
? { where: BooleanLiteral<true> }
: Trim<T> extends `WHERE ${infer Where}`
? ParseExpression<Where> extends [infer Exp, infer R0]
? Exp extends Expression
? {where: Merge<Exp>} & ParseLimitClause<R0>
: never
: never
: {where: BooleanLiteral<true>} & ParseLimitClause<Trim<T>>
type ParseLimitClause<T> =
Trim<T> extends `LIMIT ${infer R0}`
? Tokenize<R0> extends [infer Limit, infer R1]
? Limit extends keyof IntegerStrings
? {limit: IntegerStrings[Limit]} & ParseOffsetClause<R1>
: never
: never
: {limit: -1} & ParseOffsetClause<T>;
type ParseOffsetClause<T> =
Trim<T> extends `OFFSET ${infer R0}`
? Tokenize<R0> extends [infer Offset, infer R1]
? Offset extends keyof IntegerStrings
? {offset: IntegerStrings[Offset]} & ParseStatementTerminator<R1>
: never
: never
: {offset: 0} & ParseStatementTerminator<T>;
type ParseStatementTerminator<T> =
Trim<T> extends ''
? {}
: Trim<T> extends ';'
? {}
: never;
type ParseInsertStatement<T> =
T extends `INSERT INTO ${infer TableName} SET ${infer Fields}` ?
[InsertStatement<TableName, ParseAssignmentExpressionList<Fields>>, '']
: never;
type ParseUpdateStatement<T> =
T extends `UPDATE ${infer TableName} SET ${infer Fields} WHERE ${infer Where}` ?
ParseExpression<Where> extends [infer Exp, string] ?
Exp extends Expression ?
[UpdateStatement<TableName, ParseAssignmentExpressionList<Fields>, Exp>, ''] :
never :
never :
T extends `UPDATE ${infer TableName} SET ${infer Fields}` ?
[UpdateStatement<TableName, ParseAssignmentExpressionList<Fields>, BooleanLiteral<true>>, '']
: never;
type ParseDeleteStatement<T> =
T extends `DELETE FROM ${infer TableName} WHERE ${infer Where}` ?
ParseExpression<Where> extends [infer Exp, string] ?
Exp extends Expression ?
[DeleteStatement<TableName, Exp>, ''] :
never :
never :
T extends `DELETE FROM ${infer TableName}` ?
[DeleteStatement<TableName, BooleanLiteral<true>>, '']
: never;
type ParseIdentifier<T> =
T extends '' ? never :
Tokenize<T> extends [infer Head, infer Tail] ?
Head extends '' ? never :
Head extends 'null' ? [NullLiteral, Tail] :
Head extends 'true' ? [BooleanLiteral<true>, Tail] :
Head extends 'false' ? [BooleanLiteral<false>, Tail] :
Head extends keyof IntegerStrings ? [NumericLiteral<IntegerStrings[Head] & number>, Tail] :
[Identifier<Head & string>, Tail] :
[Identifier<T & string>, ''];
type ParseMemberExpression<T> =
Tokenize<T> extends [`${infer O}.${infer P}`, infer Tail] ?
[MemberExpression<O, P>, Tail]
: ParseIdentifier<T>;
type ParseStringLiteral<T> =
T extends `"${infer Value}"${infer Rest}` ? [StringLiteral<Value>, Rest] :
T extends `'${infer Value}'${infer Rest}` ? [StringLiteral<Value>, Rest] :
ParseMemberExpression<T>;
type ParseCallExpression<T> =
Trim<T> extends '' ? never :
ParseStringLiteral<Trim<T>> | ParseParenthesizedExpression<T>;
type ParseBinaryExpression<T> =
ParseCallExpression<T> extends [infer Left, infer R1] ?
Left extends Expression ?
Tokenize<R1> extends [infer Op, infer R2] ?
Op extends BinaryOperator ?
ParseCallExpression<R2> extends [infer Right, infer R3] ?
Right extends Expression ?
[BinaryExpression<Left, Op, Right>, R3] :
never :
never :
[Left, R1] :
[Left, R1] :
never :
never;
type ParseLogicalExpression<T> =
ParseBinaryExpression<T> extends [infer Left, infer R1] ?
Tokenize<R1> extends [infer Op, infer R2] ?
Op extends LogicalOperator ?
ParseExpression<R2> extends [infer Right, infer R3] ?
Left extends Expression ?
Right extends Expression ?
[LogicalExpression<Left, Op, Right>, R3] :
never :
never :
never :
[Left, R1] :
[Left, R1] :
never;
type ParseExpression<T> =
Trim<T> extends '' ? never :
ParseLogicalExpression<Trim<T>> | ParseParenthesizedExpression<T>;
type ParseParenthesizedExpression<T> = T extends `(${infer Content})${infer Rest}` ? [ParseExpression<Content>, Rest] : never;
type ParseFieldSpecifierList<T> =
T extends `${infer Head},${infer Tail}` ? [ParseFieldSpecifier<Trim<Head>>, ...ParseFieldSpecifierList<Trim<Tail>>] :
T extends `${infer Head} AS ${infer Alias} ${infer Tail}` ? [FieldSpecifier<Trim<ParseMemberExpression<Head>[0]>, Trim<ParseIdentifier<Alias>[0]>>, Tail] :
T extends `${infer Head} AS ${infer Alias}` ? [FieldSpecifier<Trim<ParseMemberExpression<Head>[0]>, Trim<ParseIdentifier<Alias>[0]>>] :
T extends `${infer Head} ${infer Tail}` ? [ParseFieldSpecifier<Trim<Head>>, Tail] :
[ParseFieldSpecifier<Trim<T>>];
type ParseFieldSpecifier<T> =
T extends `${infer Field} AS ${infer Alias}` ? FieldSpecifier<ParseMemberExpression<Trim<Field>>[0], ParseIdentifier<Trim<Alias>>[0]> :
ParseMemberExpression<T> extends [infer M, ''] ?
M extends MemberExpression<infer O, infer P> ? FieldSpecifier<M, Identifier<P>> : M extends Identifier ? FieldSpecifier<M, M> :
T extends string ? FieldSpecifier<Identifier<T>, Identifier<T>> : never :
never;
type ParseAssignmentExpressionList<T> =
T extends `${infer Head},${infer Tail}` ? [ParseAssignmentExpression<Trim<Head>>, ...ParseAssignmentExpressionList<Trim<Tail>>] :
T extends `${infer Head} = ${infer Value} ${infer Tail}` ? [AssignmentExpression<Identifier<Trim<Head>>, ParseExpression<Trim<Value>>[0] & Expression>, Tail] :
T extends `${infer Head} = ${infer Value}` ? [AssignmentExpression<Identifier<Trim<Head>>, ParseExpression<Trim<Value>>[0] & Expression>] :
T extends `${infer Head} ${infer Tail}` ? [ParseAssignmentExpression<Trim<Head>>, Tail] :
[ParseAssignmentExpression<Trim<T>>];
type ParseAssignmentExpression<T> =
T extends `${infer Key} = ${infer Value}` ? AssignmentExpression<Identifier<Key>, ParseExpression<Value>[0] & Expression> :
never;
type Tokenize<T> =
Trim<T> extends `${infer Head} ${infer Tail}` ? [Head, Tail] :
Trim<T> extends `${infer Head},${infer Tail}` ? [Head, Tail] :
Trim<T> extends `${infer Head}(${infer Tail}` ? [Head, Tail] :
Trim<T> extends `${infer Head})${infer Tail}` ? [Head, Tail] :
Trim<T> extends `${infer Head};${infer Tail}` ? [Head, Tail] :
Trim<T> extends `${infer Head})` ? [Head, ')'] :
Trim<T> extends `${infer Head};` ? [Head, ';'] :
[Trim<T>, '']