- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试解析一个类并为声明中没有值的属性声明创建默认值。
例如:
class MyClass {
name = 'My Class';
id: string;
}
functionCall<MyClass>() // <-- I get the hold of the type class here
我想生成这样的东西:
{
name: 'My Class',
id: 'I am generated'
}
我得到 MyClass
来自 functionCall<MyClass>
作为type: ts.InterfaceType
节点并从那里解析属性:
const typeChecker = program.getTypeChecker();
const type = typeChecker.getTypeAtLocation(callExpression); // This is the node where `functioCall<MyClass>()` is
type.getProperties().forEach(symbol => {
// I am stuck here
});
我遇到的问题是,一些 symbols
有symbol.valueDeclaration
as undefined 不知道用什么知道
虽然我检查了一个 symbol.valueDeclaration
存在并且如果他们的symbol.valueDeclaration.kind
是一些关键字(如 SyntaxKind.StringKeyword
)但它不适用于类似
class SomeClass {
noKeyword; // probably any?
}
如有任何帮助或指点,我们将不胜感激。
最佳答案
这是将运行时类型作为对象获取的脚本:
/*
Used to handle types from:
InterfaceDeclaration,
ClassDeclaration,
TypeLiteral
*/
function getTypeDescriptor(
property: ts.PropertyDeclaration | ts.PropertySignature,
typeChecker: ts.TypeChecker,
): ts.Expression {
const { type } = property;
if (type !== undefined) {
if (property.initializer) {
switch (property.initializer.kind) {
case ts.SyntaxKind.StringLiteral:
return ts.createLiteral('string');
case ts.SyntaxKind.FirstLiteralToken:
return ts.createLiteral('number');
}
}
return ts.createLiteral('any');
}
return getDescriptor(type, typeChecker);
}
// Create expression based on objects or property types
export function getDescriptor(type: ts.Node | undefined, typeChecker: ts.TypeChecker): ts.Expression {
if (!type) {
return ts.createLiteral('unknown');
}
switch (type.kind) {
case ts.SyntaxKind.PropertySignature:
return getDescriptor((type as ts.PropertySignature).type, typeChecker);
case ts.SyntaxKind.StringKeyword:
return ts.createLiteral('string');
case ts.SyntaxKind.NumberKeyword:
return ts.createLiteral('number');
case ts.SyntaxKind.BooleanKeyword:
return ts.createLiteral('boolean');
case ts.SyntaxKind.AnyKeyword:
return ts.createLiteral('any');
case ts.SyntaxKind.TypeAliasDeclaration:
case ts.SyntaxKind.TypeReference:
const symbol = typeChecker.getSymbolAtLocation((type as ts.TypeReferenceNode).typeName);
const declaration = ((symbol && symbol.declarations) || [])[0];
return getDescriptor(declaration, typeChecker);
case ts.SyntaxKind.ArrayType:
return ts.createArrayLiteral([getDescriptor((type as ts.ArrayTypeNode).elementType, typeChecker)]);
case ts.SyntaxKind.InterfaceDeclaration:
case ts.SyntaxKind.ClassDeclaration:
case ts.SyntaxKind.TypeLiteral:
return ts.createObjectLiteral(
(type as ts.TypeLiteralNode).members.map(member =>
ts.createPropertyAssignment(
member.name || '',
getTypeDescriptor(member as ts.PropertySignature, typeChecker),
),
),
);
default:
throw new Error('Unknown type ' + ts.SyntaxKind[type.kind]);
}
}
例子
有了这个类:
class X {
public id: number = 1;
}
属性初始值设定项如下所示:
<ref *2> TokenObject {
parent: <ref *1> NodeObject {
parent: NodeObject {
parent: [SourceFileObject],
kind: SyntaxKind.ClassDeclaration,
name: [IdentifierObject],
typeParameters: undefined,
heritageClauses: undefined,
members: [Array],
symbol: [SymbolObject]
},
kind: SyntaxKind.PropertyDeclaration,
decorators: undefined,
modifiers: [ [TokenObject], pos: 154, end: 162, transformFlags: 536870913 ],
name: IdentifierObject {},
questionToken: undefined,
type: TokenObject {
kind: SyntaxKind.NumberKeyword
},
initializer: [Circular *2],
symbol: SymbolObject {
escapedName: 'id',
declarations: [Array],
valueDeclaration: [Circular *1],
parent: [SymbolObject],
}
},
kind: SyntaxKind.NumericLiteral,
text: '1',
}
text: '1'
是属性的值,kind: SyntaxKind.NumericLiteral
是 text
的类型,parent.type.kind:SyntaxKind.NumberKeyword
是属性的实际定义类型。
P.S.:我知道的不多,但我希望它对你有所帮助
编辑:添加我如何使用转换器获取类型:
export function transformer(program: ts.Program, opts?: TransformerOptions) {
function visitor(ctx: ts.TransformationContext, sourcefile: ts.SourceFile, result: { seen: boolean }) {
const typeChecker = program.getTypeChecker();
const _visitor: ts.Visitor = (node: ts.Node) => {
if (ts.isCallExpression(node) && node.typeArguments && node.expression.getText(sourcefile) == 'generateRtti') {
const [type] = node.typeArguments;
const [argument] = node.arguments;
const fn = ts.createIdentifier(nameOfGenerateFunction);
const typeName = type.getText();
const typeSource = getDescriptor(type, typeChecker);
result.seen = true;
return ts.createCall(fn, undefined, [argument || ts.createStringLiteral(typeName), typeSource]);
}
return ts.visitEachChild(node, _visitor, ctx);
};
return _visitor;
}
return (ctx: ts.TransformationContext) => {
return (sourcefile: ts.SourceFile) => {
const result = { seen: false };
const newSourcefile = ts.visitNode(sourcefile, visitor(ctx, sourcefile, result));
if (result.seen) {
const generated_function = createGenerateFunction();
const statements: Array<ts.Statement> = [generated_function];
for (const statement of newSourcefile.statements) {
if (ts.isImportDeclaration(statement))
statements.splice(statements.length - 1, 0, statement);
else
statements.push(statement);
}
return ts.updateSourceFileNode(newSourcefile, statements);
}
return newSourcefile;
};
};
}
关于 typescript AST : How to get the asserted type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69461435/
假设a是张量,那么有什么区别: 类型(a) a.类型 a.type() 我找不到区分这些的文档。 最佳答案 type 是 python 内置方法。 它将返回对象的类型。喜欢 torch.Tensor.
什么是 Type 1 的居民的例子?两者都不是 Type也不是Type的居民?在 Idris REPL 中进行探索时,我无法想出任何东西。 更准确地说,我正在寻找一些 x除了 Type产生以下结果:
我找到了一些资源,但我不确定我是否理解。 我找到的一些资源是: http://help.sap.com/saphelp_nw70/helpdata/en/fc/eb2ff3358411d1829f00
这两个函数原型(prototype)有什么区别? void apply1(double(f)(double)); void apply2(double(*f)(double)); 如果目标是将提供的函
http://play.golang.org/p/icQO_bAZNE 我正在练习使用堆进行排序,但是 prog.go:85: type bucket is not an expression
假设有一个泛型定义的方法信息对象,即一个方法信息对象,这样的方法Info.IsGenericMethodDefinition==TRUE:。也可以说它们也有一个泛型参数列表:。我可以使用以下命令获取该
在具有依赖类型的语言中,您可以使用 Type-in-Type 来简化语言并赋予它很多功能。这使得语言在逻辑上不一致,但如果您只对编程感兴趣而不对定理证明感兴趣,这可能不是问题。 在 Cayenne
根据 Nim 手册,变量类型是“静态类型”,而变量在内存中指向的实际值是“动态类型”。 它们怎么可能是不同的类型?我认为将错误的类型分配给变量将是一个错误。 最佳答案 import typetrait
假设您有以下结构和协议(protocol): struct Ticket { var items: [TicketItem] = [] } struct TicketItem { } prot
我正在处理一个 EF 问题,我发现它很难调试...以前,在我的系统中有一个表类型继承设置管理不同的用户类型 - 所有用户共有的一种根类型,以及大致基于使用该帐户的人员类型的几种不同的子类型。现在,我遇
这是我的 DBManager.swift import RealmSwift class DBManager { class func getAllDogs() -> [Dog] {
我正在尝试使用傅里叶校正图像中的曝光。这是我面临的错误 5 padded = np.log(padded + 1) #so we never have log of 0 6 g
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
请考虑以下设置: protocol MyProcotol { } class MyModel: MyProcotol { } enum Result { case success(value:
好吧,我将我的 python 项目编译成一个可执行文件,它在我的电脑上运行,但我将它发送给几个 friend 进行测试,他们都遇到了这个错误。我以前从未见过这样的错误。我使用 Nuitka 来编译代码
当我尝试训练我的模型时"ValueError: Type must be a sub-type of ndarray type"出现在 line x_norm=(np.power(x,2)).sum(
我尝试在另一个类中打断、计数然后加入对象。所以我构建协议(protocol): typealias DataBreaker = () -> [Double] typealias DataJoiner
我正在使用 VS 2015 更新 3、Angular 2.1.2、Typescript 2.0.6 有人可以澄清什么是 typings 与 npm @types 以及本月很难找到的任何其他文档吗? 或
我正在考虑从 VS2010 更改为 Mono,因此我通过 MoMA 运行我的程序集,看看我在转换过程中可能遇到多少困难。在生成的报告中,我发现我不断收到此错误: bool Type.op_Equali
主要问题 不太确定这是否可能,但由于我讨厌 Typescript 并且它使我的编码变得困难,我想我会问只是为了确定。 interface ISomeInterface { handler: ()
我是一名优秀的程序员,十分优秀!