范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

TypeScript4。9正式发布2022。11。15官文全文翻译

  作者:Daniel Rosenwasser
  原文日期:2022.11.15
  原文链接:https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/
  今天我们很高兴地发布 TypeScript 4.9。
  如果你还不熟悉 TypeScript,TypeScript 是在 JavaScript 之上添加了类型的一个编程语言。类型帮助你标记代码的变量和函数的种类。TypeScript 可以利用这些信息,帮助你消除拼写错误,或者是不小心忘记的 null 和 undefined 的检查。但是 TypeScript 提供的远比这些多,TypeScript 可以用这些信息极大地提升你的开发体验,提供例如代码补全,跳转定义,重命名等功能。如果你已经用 Visual Studio 或者 Visual Studio Code 进行编写 JavaScript 的项目,你其实已经间接使用了 TypeScript!
  开始使用 TypeScript,你可以通过 NuGet,或者 npm 通过下面这个命令:npm install -D typescript
  你通过以下方式获取编辑器:下载 Visual Studio 2022/2019安装 Visual Studio Code 或者根据文档去使用更新版本的 TypeScript
  这里是 TypeScript 4.9 更新的内容satifies 操作符in 操作符中未列举的属性收束Class 的 Auto-Accessor对于 NaN 进行检查通过文件系统事件检测文件编辑器增强:"Remove Unused Imports" 和 "Sort Imports"编辑器增强:对于 return 关键字的 Go-to-Definition性能增强正确性修复和破坏性改变从 Beta 和 RC 版本依赖的更新
  相比 RC 版本,没有更多的变化加入到 TypeScript 4.9。Beta 版本本来包括 Class 的 Auto-Accessor 性能改进的部分,但是没有列出在文档上。satisfies 操作符
  TypeScript 开发者经常面对这样一个难题:我们需要保证一些表达式匹配一些类型,但是又希望保留这个类型更具体的形状。
  例如:// 每一个属性,既可以是RGB 元组,也可以是一个字符串。 const palette = {     red: [255, 0, 0],     green: "#00ff00",     bleu: [0, 0, 255] //  ^^^^ sacrebleu - 这里故意写错了! };  // 我们对于 red 使用数组的方法... const redComponent = palette.red.at(0);  // 或者对于 green 使用 string 的方法... const greenNormalized = palette.green.toUpperCase();
  注意这里故意写成了 bleu, 而实际上应该写成 blue。 我们可以通过给 palette 加一个类型标准来避免这种问题, 但是这样我们又失去具体一个属性的具体类型了。type Colors = "red" | "green" | "blue";  type RGB = [red: number, green: number, blue: number];  const palette: Record = {     red: [255, 0, 0],     green: "#00ff00",     bleu: [0, 0, 255] //  ~~~~ 写错就会报错 };  // 但是 red 可能是一个 string,而在上面的表达式中,实际是一个数组。 const redComponent = palette.red.at(0);
  新的 satisfies 关键字就是用来解决这个问题的。satisfies 可以用来校验一个更具体的形状是否符合预设的形状。我们用 satisfies 来解决上面的问题。type Colors = "red" | "green" | "blue";  type RGB = [red: number, green: number, blue: number];  const palette = {     red: [255, 0, 0],     green: "#00ff00",     bleu: [0, 0, 255] //  ~~~~ 写错就会报错,satisfies 会去校验! } satisfies Record;  // 但是! const redComponent = palette.red.at(0); const greenNormalized = palette.green.toUpperCase();
  (Hugo 注:satisfies 能实现编译态和运行态更一致的类型关系,satisfies 有点像 ts 的 ts)
  satisfies 可以用来捕获很多可能的错误。例如,我们可以保证一个 object 的 key 只能是有限的集合中的结果。type Colors = "red" | "green" | "blue";  // 保证所有的 key 都来自 "Colors". const favoriteColors = {     "red": "yes",     "green": false,     "blue": "kinda",     "platypus": false //  ~~~~~~~~~~ error - "platypus" 并不在 "Colors" 中. } satisfies Record;  //所有关于 "red", "green", 和 "blue" 的属性信息都是和值声明一致的. const g: boolean = favoriteColors.green;
  也许我们不关心 object 的 key 因为名称,而更关心 value 的类型。在下面的例子中,也可以解决这样的问题:type RGB = [red: number, green: number, blue: number];  const palette = {     red: [255, 0, 0],     green: "#00ff00",     blue: [0, 0]     //    ~~~~~~ error! } satisfies Record;  // 所有值的类型和上面的值声明是一致的. const redComponent = palette.red.at(0); const greenNormalized = palette.green.toUpperCase();
  如果你想看更多的例子,可以查看 issue 和 pr。我们感谢 Oleksandr Tarasiuk 实现了这个功能。in 操作符中未列举的属性收束
  作为开发者,我们经常需要处理程序运行时不完全知道的类型。事实上,我们从服务器或者配置文件读一个数据,并不能完全确定这个属性是否存在,JavaScript 的 in 操作符提供了检查一个字段是否存在的手段。
  在之前,TypeScript 也提供了一定的对使用 in 操作符进行类型收束。interface RGB {     red: number;     green: number;     blue: number; }  interface HSV {     hue: number;     saturation: number;     value: number; }  function setColor(color: RGB | HSV) {     if ("hue" in color) {         // "color"d HSV     }     // ... }
  类型 RGB 并没有 hue 字段,所以可以进行类型收束,在 in 的 block 中,类型被收束为 HSV。
  但是,如果没有进行类型标准,会变成什么样子呢?function tryGetPackageName(context) {     const packageJSON = context.packageJSON;     // 检查我们收到的类型是一个 object.     if (packageJSON && typeof packageJSON === "object") {         // 检查存在 name 字段.         if ("name" in packageJSON && typeof packageJSON.name === "string") {             return packageJSON.name;         }     }      return undefined; }
  把上面的例子改写为 TypeScript,并使用 unknown 类型。interface Context {     packageJSON: unknown; }  function tryGetPackageName(context: Context) {     const packageJSON = context.packageJSON;     // 检查我们收到的类型是一个 object.     if (packageJSON && typeof packageJSON === "object") {         // 检查存在 name 字段.         if ("name" in packageJSON && typeof packageJSON.name === "string") {         //                                              ~~~~         // error! Property "name" does not exist on type "object.             return packageJSON.name;         //                     ~~~~         // error! Property "name" does not exist on type "object.         }     }      return undefined; }
  这里会报错是因为,在之前的版本,虽然 unkown 被收束为 object,但是之后的收束并没有生效,TypeScript 依然认为 packageJSON 只是一个 object,而不知道有 name 这个字段。
  TypeScript 4.9 会更智能,在通过 in 操作符以后,会给类型添加上断言添加的类型 Record<"property-key-being-checked", unknown>。
  所以,在 TypeScript 4.9 中,packageJSON 的类型会先从 unknown 收束为 object,然后继续收束为 object & Record<"name", unknown>。这样后续的操作就知道 packageJSON 有 name 这个字段。interface Context {     packageJSON: unknown; }  function tryGetPackageName(context: Context): string | undefined {     const packageJSON = context.packageJSON;     // 检查我们收到的类型是一个 object.     if (packageJSON && typeof packageJSON === "object") {         // 检查存在 name 字段.         if ("name" in packageJSON && typeof packageJSON.name === "string") {             // 不会报错了!             return packageJSON.name;         }     }      return undefined; }
  TypeScript 也会对 in 操作符两端做检查,确保左边是 string | number | symbol, 右边是 object。这会保证我们检查的左边是合法的 key,而右边不是在检查一个基础类型。
  更多的信息请查看 pr。
  (Hugo 注,这个功能虽然简单,但是让 TypeScript 的断言能力进一步提升,在核心关键点写出更安全的代码提供了方便。)Auto-Accessors in Classes
  TypeScript 只吃了 ECMAScript 的新功能 auto-accessors。auto-accessors 就和 class 的属性一样, chclass Person {     accessor name: string;      constructor(name: string) {         this.name = name;     } }
  上面这个写法,在最后会被去糖味 get 和 set 以及不可访问的原生私有属性。class Person {     #__name: string;      get name() {         return this.#__name;     }     set name(value: string) {         this.#__name = name;     }      constructor(name: string) {         this.name = name;     } }
  对这个功能关心的话,请查看 pr。对于 NaN 进行检查
  对于 JavaScript 开发者来说,检查一个值和 NaN 的关系是一件不容易的事。
  NaN 是一个特殊的数字型值,表示 "不是一个数字"。什么值和 NaN 都不相等,包括 NaN 自己。console.log(NaN == 0)  // false console.log(NaN === 0) // false  console.log(NaN == NaN)  // false console.log(NaN === NaN) // false
  和这个等价的另一个规则是,任何东西都和 NaN 不相等。console.log(NaN != 0)  // true console.log(NaN !== 0) // true  console.log(NaN != NaN)  // true console.log(NaN !== NaN) // true
  这个奇怪的行为并不是 JavaScript 独有的,任何语言只要实现了 IEEE-754 floats 标准,就会有这个行为。但是 JavaScript 的原生数字类型是一个浮点数型数字值,并且 JavaScript 的数字解析经常会出现 NaN。检查和 NaN 在处理数字相关的代码时,是非常常见的。通常使用 Number.isNaN,但是就像上面提到的,很多开发者实际使用 someValue === NaN 来实现这个功能。
  TypeScript 会对 NaN 的直接比较进行报错,提示开发者使用 Number.isNaN(Hugo 注:多么贴心的功能。)。function validate(someValue: number) {     return someValue !== NaN;     //     ~~~~~~~~~~~~~~~~~     // error: This condition will always return "true".     //        Did you mean "!Number.isNaN(someValue)"? }
  我们认为这个改变能帮助新手开发者防止错误,就像 TypeScript 目前不可以比较 object 和 array 一样。
  感谢 Oleksandr Tarasiuk 贡献了这个 PR。通过文件系统事件检测文件
  在早期的版本里,TypeScript 非常依赖轮训来检测单个文件。使用轮训的机制表示,TypeScript 需要周期的检查一个文件。在 Node.js 里, fs.watchFIle 时内置的获取轮训文件检测器的内置方法。因为轮训的机制在不同的平台和文件系统中是比较确定的,它会时不时终端 CPU 来看这个文件的状态,即便这个文件啥也没做,也要发生中断。如果文件不多,这个机制是合适的。但是如果文件特别多,比如 node_modules 里的那么多文件,这种机制会造成一些资源占用浪费。
  通常来说,比较好的方法是通过文件系统事件来实现上面的机制。不再使用轮训的机制,我们可以关注关心的文件,然后通过事件触发的回调来实现。绝大部分现代平台提供了CreateIoCompletionPort, kqueue, epoll, 和 inotify。Node.js 提供了[fs.watch]() ,这个接口抽象了这些实现方式。使用 fs.watch 接口来使用文件系统事件通常工作很好,但是也有一些缺陷。一个检测者要小心考虑 inode watching,在一些文件系统不可用(比如网络文件系统)。是否有递归文件检测是可用的,文件夹改名是否触发事件, 还有文件检测者耗尽的问题。换句话说,使用这个机制,需要考虑非常多的问题,尤其是在跨平台使用时。
  所以目前的解决方案时,我们默认的方法是在绝大部分时间使用轮训。
  随着时间发展,我们会提供其他的文件检测机制。这让我们可以更多地获得关于跨平台碰到相关问题的反馈。因为 TypeScript 的项目会扩展为非常大的代码库,我们认为切换到基于文件事件的机制是值得投资的事情。
  在 TypeScript 4.9, 文件检测默认使用文件系统事件,只有在设置事件检测者失败时回退成轮训的机制。对于绝大部份开发者,使用 —watch 模式可以消耗更少的资源,在使用 TypeScript 强化的编辑器例如 Visual Studio 或者 VS Code 时也会使用更少的资源。
  使用 watchOptions 可以改变这个机制。VS Code 也提供了改变这个参数的方法。如果开发者使用网络文件系统(例如 NFS 和 SMB),需要把这个参数回退成轮训的机制,当然直接在服务器端使用 TypeScript 也是一个不错的选择,这样就是使用本地文件系统了。VS Code 有很多关于远程开发的插件来帮助这个过程。
  你可以在这篇文章看到关于这个问题更多的信息。编辑器增强:"Remove Unused Imports" 和 "Sort Imports"
  在之前的版本,TypeScript 只支持两个编辑器命令来管理 import。 例如import { Zebra, Moose, HoneyBadger } from "./zoo"; import { foo, bar } from "./helper";  let x: Moose | HoneyBadger = foo();
  第一个时 "Organize Imports",会把不使用的 imports 移除,然后对剩下的 import 进行排序。上面的文件会被重写为:import { foo } from "./helper"; import { HoneyBadger, Moose } from "./zoo";  let x: Moose | HoneyBadger = foo();
  在 TypeScript 4.3, 我们引入了 "Sort Import" 命令,可以只对文件进行排序,而不移除它们,使用这个功能会让一开始的代码变为import { bar, foo } from "./helper"; import { HoneyBadger, Moose, Zebra } from "./zoo";  let x: Moose | HoneyBadger = foo();
  使用 "Sort Imports" 的缺陷是,在 Visual Studio Code 中,这个功能只能是保存时调用的功能,而不是手动触发的功能。
  TypeScript 4.9 增加了另一半功能,即 "Remove Unused Imports",TypeScript 可以移除不使用的 import 和语句,把剩下的代码留下。import { Moose, HoneyBadger } from "./zoo"; import { foo } from "./helper";  let x: Moose | HoneyBadger = foo();
  这个功能对于全部编辑器可用,但是注意 Visual Studio Code(1.73 和之后)会支持内置的可以在命令面板调用的这些功能。用户如果想更细粒度地控制这个行为,可以混合调用 "Remove Unused Imports"、"Sort Imports" 和 "Organize Imports"。
  更详细的文档请参考。编辑器增强:对于 return 关键字的 Go-to-Definition
  在编辑器中,当对 return 关键字执行 go-to-definition,TypeScript 会跳到相关函数的顶部。这对于知道这个 return 属于哪个函数是有帮助的。
  我们期望 TypeScript 可以扩展这个行为到更多的关键字,比如 await 和 yield,switch、case 和 default。
  感谢 Oleksandr Tarasiuk 提供了这个实现。性能增强
  TypeScript 有了一些小但是值得注意的性能增强。
  首先,TypeScript 的 forEachChild 函数使用函数表查找重写了 switch 语句的实现。编译器在进行语法节点遍历时非常依赖 forEachChild,并且在语言服务器的编译器链接阶段也用的很重。重构 forEachChild 带来了绑定阶段大约 20% 的性能提升。
  当我们最终发现这个优化对于 forEachChild 的实现很有效果,我们在 visitEachChild(这个函数在编译器和语言服务器中进行转换节点的工作)也做一样的优化。这样大概提升了 visitEachChild 3% 的性能。
  最开始对于 forEachChild 优化的启发是来自Artemis Everfree 的博客。虽然我们认为目前速度的问题更多是函数的大小和复杂性有关,并不是博文中指出的问题,但是我们对于从这个经验中找到这个优化方法是非常感激的。
  最后,对于 TypeScript 在条件分支中保留类型信息做了一些优化,对于类型interface Zoo {     // ... }  type MakeZoo = A extends Animal ? Zoo : never;
  TypeScript 在检查 Zoo 是合法时需要知道 A 是一个 Animal。在之前的版本,TypeScript总是立即做了这件事,目前看是不必要的。并且,一些我们的类型检查器中的错误代码让我们无法简化这个过程。TypeScript 现在推迟到必须知道这个类型时再去检查类型。对于使用条件类型非常多的代码库,能看到非常大的性能提升,对于常规情况,我们看到 3% 的类型检查时间提升。
  你可以阅读下面的 PR 来了解更详细的信息[forEachChild as a jump-table](https://github.com/microsoft/TypeScript/pull/50225)[visitEachChild as a jump-table](https://github.com/microsoft/TypeScript/pull/50266)Optimize substitition types正确性修复和破坏性改变更新 lib.d.ts
  虽然 TypeScript 尽量避免大的破坏式更新,因为内置库的一点小变化也会导致一些问题,但是关于 DOM 和 lib.d.ts 仍然会有一些小的破坏式更新。对于 Promise.resolve 的类型增强
  Promise.resolve 现在使用 Awaited 类型来对 Proimse-like 的类型进行解包。这意味着现在更多返回正确的 Promise 的类型,而不是 any 或者 unknown。更与这个变更更多请参考。JavaScript不再触发省略 import
  当 TypeScript 编译器开始支持 JavaScript 的类型检查和编译时,TypeScript 引入了一些机制,例如省略 import。这个功能的意思是,如果编译器发现一个引入的东西不作为值,则会在最终生成的文件省略这个 import。
  现在,TypeScript 会保留这些 import。// 输入: import { someValue, SomeClass } from "some-module";  /** @type {SomeClass} */ let val = someValue;  // 之前版本的输出: import { someValue } from "some-module";  /** @type {SomeClass} */ let val = someValue;  // 现在的输出: import { someValue, SomeClass } from "some-module";  /** @type {SomeClass} */ let val = someValue;
  更多关于这个内容的信息参考。exports 优先级高于 typesVersions
  在之前的版本中,当 TypeScript 解析 package.json 通过 --moduleResolution node16 时,TypeScript 会错误提升 typesVersions 的优先级高于 exports。如果这个改变影响你的库,你需要增加 types@ 字段。{       "type": "module",       "main": "./dist/main.js"       "typesVersions": {           "<4.8": { ".": ["4.8-types/main.d.ts"] },           "*": { ".": ["modern-types/main.d.ts"] }       },       "exports": {           ".": { +             "types@<4.8": "4.8-types/main.d.ts", +             "types": "modern-types/main.d.ts",               "import": "./dist/main.js"           }       }   }
  更多信息参考。(Hugo 注:这种类型的功能,建议等三个版本再上生产。)对于 SubstitutionType 的 substitute 替换为 constraint
  对于替换类型的优化,SubstitutionType 对象不在包含 substitute 属性,substitute 属性代表高效替换,通常是基础类型和隐式限制的交集。现在 SubstitutionType 值包含 constraint 属性。
  更多信息,参考。下一步
  我们目前发布了了 5.0 版本的迭代计划,里面有很多有趣的功能!如果你感兴趣,我们期望你们能来看看。
  期望 4.9 让你的代码旅途更快乐。
  Happy Hacking!
  – Daniel Rosenwasser and the TypeScript Team

崔茂虎被查!真正的中央级大老虎,从政33年,一路晋升,一路狂飙国家打虎拍蝇的力度越来越强,连续三天打了三只老虎,老百姓们拍案叫绝。公务员周六本来是休息日,而就在3月18日星期六上午10点,中央纪委官方发文,中央统战部原副部长崔茂虎被调查!这可家,是教育的根一个负责任的家长,不仅要做好孩子第一任老师的工作,还要准备做好孩子的终身老师的工作。没有家长不重视孩子的教育。有些家长早早就把孩子送进早教机构,希望能赢在起跑线上。他们将孩子送进最明洪熙宣德时期的政治变革,以及带来的社会繁荣朱棣去世后,其长子朱高炽于永乐二十二年(1424)即位,改次年为洪熙元年。他与朱标朱允坟一样,是受儒学熏陶较深的学者式的君主,与儒臣集团相交甚厚。做太子的时候,朱高炽的地位曾受其弟打虎永远不停歇,反腐决心如磐石,盘点今年10个被查的省部级高官3月18日消息,中央统战部原副部长国家宗教事务局原局长崔茂虎涉嫌严重违纪违法,目前正接受中央纪委国家监委纪律审查和监察调查。而加上今天这位大老虎,这是今年被查的第10名中管干部,也41岁116天,伊布拉希莫维奇成意甲最年长进球者北京时间19日凌晨,意甲第27轮,AC米兰客场13不敌乌迪内斯,近3轮联赛不胜。本场比赛,现年41岁166天的瑞典球星伊布拉希莫维奇为红黑军团打入唯一进球。凭借此球,他成为意甲改制AI美女篮球宝贝(以下图片均由AI生成)点个关注不迷路!还想看啥样的AI美女,留言告诉我!点个关注不迷路!还想看啥样的AI美女,留言告诉我!点个关注不迷路!还想看啥样的AI美女,留言告诉我!点个关昆山龙哥事件,无罪释放并不是最大的正义1我只说法律规定,只说事实,因为猜测不会作为法院的证据。2我认为,如果是在社会龙逃跑之前被砍死,可以理解为正当防卫,但是追砍行为就造成了争议。3被口头威胁而没有实际行为,不应当作为李梦事件爆发,是渣男存心所致!给妻子画大饼开始其自私属性曝光这几天刷新闻,刷到了关于明星球员李梦的新闻,只想说李梦,你糊涂啊。据悉一个名叫时势艰难123的网友突然在网络上求助,称女篮李梦与自己丈夫张隆大搞婚外情!随后贴出李梦的大尺度照片。毕李梦事件开始发酵,当事人再发狠话,短短10个字让李梦无地自容北京时间3月19日,近日,一则关于李梦的微博在社交媒体上广为流传,这也让李梦一度登上了热搜。根据前女篮领队张隆妻子爆料,女篮国手李梦作为第三者插足他们之间的婚姻,搞得她的家庭支离破先进封装与异构集成路线图信息与通信技术(ICT)是那些需要移动存储计算通信和保护的数据呈指数级增长的来源。依赖于特征尺寸缩减(维度缩放)的传统半导体技术即将达到其物理极限,在提高系统性能方面仍面临重大挑战荣耀虎口夺食,5100mAh大电量120Hz曲面屏轻薄设计,流畅36个月手机是我们现在每天都会用到的智能上网设备,自从网络的发展普及,给我们的工作生活学习带来超多便利,大家通过网络可以学习到世界各地的风土人情,增长见识的同时可以有更多的欢乐,可以说网络
下架一年多,滴滴又出事了?15家出行公司再遭集体约谈!作者Hernanderz监制罗超2022年最后一个工作日,滴滴投资者的神经再次紧张起来了。据交通运输部官方消息,交通运输新业态协同监督部联席会议办公室对滴滴出行等15家平台进行提醒奥运冠军张雨霏入选2022年最美大学生候选资料图2022年7月29日,中国游泳小花张雨霏在女子200米蝶泳决赛中,以2分03秒86力压强敌夺得冠军。这是中国泳军在东京奥运赛场收获的首枚金牌,同时也是中国代表团的第13金。中周冬雨终于穿对了,黑色抹胸连体裤剪俩洞,平板身材也撩人!这是一个看脸的时代,拥有完美的身材和超高的颜值,人生就会像开挂一样顺风顺水,所以有越来越多的女孩子都纷纷走上了身材管理的道路,都希望能够通过对身材的管理来获得一定的关注度,但是如何天地有大美问道崆峒山伟哉!崆峒山,中华道教第一山曾祥裕曾海亮从赣州出发寻访天下崆峒山祖庭,当我们登上平凉崆峒山山巅时,眺望远方,云蒸霞蔚,层峦叠嶂,气象万千。伟哉!崆峒山,自古就有中华道教第一山之美誉当年街机厅十大神作从街霸到拳皇再到吞食天地,你都玩过哪款?对于许多80和90年代出生的玩家来说,他们记忆中最深刻的游戏瞬间会是什么时候呢?是假期在电脑前,为了艾泽拉斯大陆的荣光而奋斗?是童年时与小伙伴们一起,钻研如何找到魂斗罗的水下八关?奇遇甘肃,遇见未知的旅途携程大咖旅行团走进甘肃,邂逅陇原天地间的冬日风光君不到西北,焉知中华大地之广博君不到甘肃,焉知西北大地之辽阔。甘肃这片充满奇幻和惊喜的土地,如同莫高窟的飞天壁画,舞动在大漠敦煌如同扎尕那的逐日经幡,摇曳在秘境甘南如同丹霞山的盛世华为P60将在第一季度发布,采用麒麟最新款芯片,依旧没有5G近期华为P60的消息越来越多,这一切似乎都在证明着这款手机将在今年第一季度发布,预计在2月底到3月初。而关于华为P60的外观图也是不少,首先就是手机壳的爆料,这次的华为P60和上一全域旅游风帆劲魅力瑶山迎客来来源人民网广西频道原创稿近日,自治区文化和旅游厅公布2022年广西全域旅游示范区名单,都安瑶族自治县上榜,荣获广西全域旅游示范区称号。这份荣誉为都安进一步提升全域旅游发展水平,建设日本大阪(Osaka)2美丽的岸和田城是岸和田的地标,建于昭和时代。还有被指定为国家名胜的岸和田城庭,是当地人喜欢休闲的地方。郡山城由封建军阀筒井顺庆建造。据说,这些樱花树是丰臣秀长定居时移栽而来的。江户解禁后的第一个小长假,旅游业恢复情况并不理想不再有行程码健康码核酸检测,也不再有疫情导致的限流。2023年的第一个小长假,是一切都恢复如常的第一个小长假。旅游业回来了人从众情景再现各地回暖的报道层出不穷,阳康人奔赴三亚带来的新春走基层临夏市让冰天雪地变成旅游热资源新甘肃甘肃日报记者王虎通讯员李洋洋李鋆刚滑雪太好玩了,真刺激!又摔了个四脚朝天,哈哈无动力戏雪区里热闹非凡,雪地冰雪滑道刺激又解压,尖叫声此起彼伏,高坡雪圈雪船雪地摩托车雪地坦克雪