ServiceStack - 如何添加自定义打字稿装饰器?
ServiceStack - how to add custom typescript decorators?
我正在通过 ServiceStack 下的 C# 模型生成打字稿 dto。
我希望使用 typestack/class-validator,它通过评估它提供的几个装饰器来运行。
在 ServiceStack 的打字稿生成中,是否有一种方法可以在 C# 端包含超出常规 DataAnnotations 属性的任意装饰器,或者我必须创建新的 C# 属性来反映我想在打字稿端显示的内容?
编辑:
由于 更 UX-friendly 我还决定实现此功能,您可以在其中使用 [Emit{Language}]
属性在每种类型或 属性 之前生成代码,例如:
[EmitTypeScript("@Validate()")]
public class User
{
[EmitTypeScript("@IsNotEmpty()", "@IsEmail()")]
public string Email { get; set; }
}
您还可以使用 [EmitCode]
发出多种语言的代码,例如这会为 Dart 和 TypeScript 添加注释。
[EmitCode(Lang.Dart | Lang.TypeScript, "@Validate()")]
public class User
{
[EmitCode(Lang.Dart | Lang.TypeScript, new[]{ "@IsNotEmpty()", "@IsEmail()" })]
public string Email { get; set; }
}
此外,您可以使用 PreTypeFilter
、InnerTypeFilter
和 PostTypeFilter
在类型定义前后生成源代码,例如这将在非枚举类型上附加 @validate()
注释:
TypeScriptGenerator.PreTypeFilter = (sb, type) => {
if (!type.IsEnum.GetValueOrDefault())
{
sb.AppendLine("@Validate()");
}
};
InnerTypeFilter
在类型定义之后被调用,可用于为所有类型和接口生成公共成员,例如:
TypeScriptGenerator.InnerTypeFilter = (sb, type) => {
sb.AppendLine("id:string = `${Math.random()}`.substring(2);");
};
它们以前不存在,但我也刚刚添加了 PrePropertyFilter
& PostPropertyFilter
用于在属性前后生成源代码,例如:
TypeScriptGenerator.PrePropertyFilter = (sb , prop, type) => {
if (prop.Name == "Id")
{
sb.AppendLine("@IsInt()");
}
};
Pre/Post PropertyFilter 从 v5.9.3+ 开始可用,现在是 available on MyGet.
在@mythz 增强功能之上,这是我最终目标的简洁镜头...
定义 c# 属性 class 以允许使用装饰器装饰 c# 属性,并将代码生成到相应的打字稿 dtos 中:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class TypeScriptDecoratorsAttribute : Attribute
{
public string[] Decorators { get; set; }
public TypeScriptDecoratorsAttribute(params string[] decorators)
{
this.Decorators = decorators;
}
}
然后使用新的 PrePropertyFilter
发出:
(例如 Startup.cs)
TypeScriptGenerator.PrePropertyFilter = (sb, prop, type) =>
prop.PropertyInfo.FirstAttribute<TypeScriptDecoratorsAttribute>()?.Decorators?.ForEach(d=> sb.AppendLine("// "+d));
仅供参考,Enumerable.ForEach() 来自 System.Interactive.
所以这个示例 c# dto:
public class User
{
[TypeScriptDecorators("@IsNotEmpty()", "@IsEmail()")]
public string Email { get; set; }
}
将产生此打字稿 dto 输出:
export class User
{
// @IsNotEmpty()
// @IsEmail()
public email?: string;
public constructor(init?: Partial<User>) { (Object as any).assign(this, init); }
}
我正在通过 ServiceStack 下的 C# 模型生成打字稿 dto。
我希望使用 typestack/class-validator,它通过评估它提供的几个装饰器来运行。
在 ServiceStack 的打字稿生成中,是否有一种方法可以在 C# 端包含超出常规 DataAnnotations 属性的任意装饰器,或者我必须创建新的 C# 属性来反映我想在打字稿端显示的内容?
编辑:
由于 [Emit{Language}]
属性在每种类型或 属性 之前生成代码,例如:
[EmitTypeScript("@Validate()")]
public class User
{
[EmitTypeScript("@IsNotEmpty()", "@IsEmail()")]
public string Email { get; set; }
}
您还可以使用 [EmitCode]
发出多种语言的代码,例如这会为 Dart 和 TypeScript 添加注释。
[EmitCode(Lang.Dart | Lang.TypeScript, "@Validate()")]
public class User
{
[EmitCode(Lang.Dart | Lang.TypeScript, new[]{ "@IsNotEmpty()", "@IsEmail()" })]
public string Email { get; set; }
}
此外,您可以使用 PreTypeFilter
、InnerTypeFilter
和 PostTypeFilter
在类型定义前后生成源代码,例如这将在非枚举类型上附加 @validate()
注释:
TypeScriptGenerator.PreTypeFilter = (sb, type) => {
if (!type.IsEnum.GetValueOrDefault())
{
sb.AppendLine("@Validate()");
}
};
InnerTypeFilter
在类型定义之后被调用,可用于为所有类型和接口生成公共成员,例如:
TypeScriptGenerator.InnerTypeFilter = (sb, type) => {
sb.AppendLine("id:string = `${Math.random()}`.substring(2);");
};
它们以前不存在,但我也刚刚添加了 PrePropertyFilter
& PostPropertyFilter
用于在属性前后生成源代码,例如:
TypeScriptGenerator.PrePropertyFilter = (sb , prop, type) => {
if (prop.Name == "Id")
{
sb.AppendLine("@IsInt()");
}
};
Pre/Post PropertyFilter 从 v5.9.3+ 开始可用,现在是 available on MyGet.
在@mythz 增强功能之上,这是我最终目标的简洁镜头...
定义 c# 属性 class 以允许使用装饰器装饰 c# 属性,并将代码生成到相应的打字稿 dtos 中:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class TypeScriptDecoratorsAttribute : Attribute
{
public string[] Decorators { get; set; }
public TypeScriptDecoratorsAttribute(params string[] decorators)
{
this.Decorators = decorators;
}
}
然后使用新的 PrePropertyFilter
发出:
(例如 Startup.cs)
TypeScriptGenerator.PrePropertyFilter = (sb, prop, type) =>
prop.PropertyInfo.FirstAttribute<TypeScriptDecoratorsAttribute>()?.Decorators?.ForEach(d=> sb.AppendLine("// "+d));
仅供参考,Enumerable.ForEach() 来自 System.Interactive.
所以这个示例 c# dto:
public class User
{
[TypeScriptDecorators("@IsNotEmpty()", "@IsEmail()")]
public string Email { get; set; }
}
将产生此打字稿 dto 输出:
export class User
{
// @IsNotEmpty()
// @IsEmail()
public email?: string;
public constructor(init?: Partial<User>) { (Object as any).assign(this, init); }
}