通过适当的自动完成(IntelliSense)将JSON强制转换为PowerShell

问题描述 投票:1回答:2

有没有办法在Visual Studio代码中使用IntelliSense自动完成自动完成功能,当我读取一个json文件并将其转换为PowerShell时:

$config = Get-Content "SOME_PATH" | ConvertFrom-Json
$config.attribute1 

问题是文件需要在内存中才能从json文件中获取结构并提出属性。

如果我将代码输出并在powershell终端中执行,然后返回代码编辑器,则自动完成工作正常。

json powershell visual-studio-code
2个回答
2
投票

目前,IntelliSense不会这样做。

其中一些原因是因为当您编码时,通常指定的文件不存在,测试版本与预期不同,文件可能会很大,格式错误等。默认情况下,有时候更不安全。

通过在终端中运行它并将其加载到内存中,您明确告诉IntelliSense您正在使用什么,然后它现在“知道”该对象,然后可以正确地建议正确的属性和属性。

正如@ mklement0建议的那样,使用键盘快捷键F8将方便地执行集成终端中的当前行/选择,这将把对象加载到内存中,并允许您在编辑器中使用IntelliSense。


1
投票

补充HAL9256's helpful answer

一,背景资料;在底部找到一个有效的解决方案。

Visual Studio Code中的变量IntelliSense的工作类型如下:

  • 明确声明(例如,[datetime] $var = ...
  • 或者可以从指定的值推断出来。

如果赋值基于命令(cmdlet,function,script)调用,则只能从具有显式定义的输出类型的命令推断出类型:

  • 很多,但绝不是全部,cmdlet确实声明了它们的输出类型
  • 函数和脚本必须使用[OutputType(<type>)]属性。

此外,由[pscustomobject]返回的不起眼的ConvertFrom-Json类型 - 没有固有的属性,只有你按需添加的那些;一个“属性包” - 你只获得智能感知:

  • 如果从自定义对象文字中分配变量(例如,$var = [pscustomobject] @{ one = 1; two = 2 }
  • 如果将自定义对象强制转换为特定类型,假设可以从自定义对象的属性构造该类型的实例,那么PowerShell可以轻松实现 - 请参阅this answer

Solution with a custom class (PSv5+)

Visual Studio Code的IntelliSense(通过PowerShell扩展)确实识别通过PSv5 + class statement定义的PS自定义类的实例成员。

因此,您可以使用自定义类来镜像正在加载的JSON对象的结构,并通过强制转换将[pscustomobject]返回的ConvertFrom-Json“属性包”转换为该类的实例。

注意:此方法的固有限制是您的类必须预期底层JSON对象包含的所有属性名称,并且两者必须保持同步;除此以外:

  • 如果JSON端的属性名称发生更改,则如果类定义未相应更新,则代码将中断。
  • 如果在JSON端添加了新属性,除非相应地更新类定义,否则这些属性将无法访问。

class定义可以是:

  • 直接嵌入脚本中
  • 通过using module statement从模块导入(请注意,使用Import-Module不会加载模块的类)。

要实现手头的解决方案,您可以通过以下两种方式之一使用class定义:

  • (a)直接在脚本中定义一个与JSON对象结构相匹配的class,并将从[pscustomobject]返回的ConvertFrom-Json实例转换为该类型;以这种方式分配的变量支持IntelliSense。
  • (b)将JSON加载功能包装在模块中执行上述操作的模块中,并将class实例从声明其[OutputObject()]的函数传递出来;使用using module导入该模块的代码将获取用于捕获该函数输出的变量的IntelliSense。

(a)的简单演示:

# Define a class whose properties mirror the underlying JSON.
class Config {
  $foo
  $bar
}

# Load the JSON and cast the resulting [pscustomobject] to the class.
# Note: This cast only works if the JSON object's set of properties 
#       is either the same as that of the [Config] type or a subset of it.
[Config] $config = '{ "foo": "bar", "bar": 42 }' | ConvertFrom-Json

# Variable $config supports IntelliSense, because its is now known
# as type Config.
$config. # shows list of properties
© www.soinside.com 2019 - 2024. All rights reserved.