mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
fix(55994): Type-check Import Attributes in static imports (#56034)
This commit is contained in:
parent
9999f26483
commit
72d497352f
@ -325,6 +325,7 @@ import {
|
||||
getModeForUsageLocation,
|
||||
getModifiers,
|
||||
getModuleInstanceState,
|
||||
getNameFromImportAttribute,
|
||||
getNameFromIndexInfo,
|
||||
getNameOfDeclaration,
|
||||
getNameOfExpando,
|
||||
@ -407,6 +408,7 @@ import {
|
||||
IdentifierTypePredicate,
|
||||
idText,
|
||||
IfStatement,
|
||||
ImportAttribute,
|
||||
ImportAttributes,
|
||||
ImportCall,
|
||||
ImportClause,
|
||||
@ -553,6 +555,7 @@ import {
|
||||
isIdentifierTypePredicate,
|
||||
isIdentifierTypeReference,
|
||||
isIfStatement,
|
||||
isImportAttributes,
|
||||
isImportCall,
|
||||
isImportClause,
|
||||
isImportDeclaration,
|
||||
@ -2179,6 +2182,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
var deferredGlobalImportMetaType: ObjectType;
|
||||
var deferredGlobalImportMetaExpressionType: ObjectType;
|
||||
var deferredGlobalImportCallOptionsType: ObjectType | undefined;
|
||||
var deferredGlobalImportAttributesType: ObjectType | undefined;
|
||||
var deferredGlobalDisposableType: ObjectType | undefined;
|
||||
var deferredGlobalAsyncDisposableType: ObjectType | undefined;
|
||||
var deferredGlobalExtractSymbol: Symbol | undefined;
|
||||
@ -11555,6 +11559,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true, CheckMode.Normal), declaration, reportErrors);
|
||||
}
|
||||
|
||||
function getTypeFromImportAttributes(node: ImportAttributes): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
const symbol = createSymbol(SymbolFlags.ObjectLiteral, InternalSymbolName.ImportAttributes);
|
||||
const members = createSymbolTable();
|
||||
forEach(node.elements, attr => {
|
||||
const member = createSymbol(SymbolFlags.Property, getNameFromImportAttribute(attr));
|
||||
member.parent = symbol;
|
||||
member.links.type = checkImportAttribute(attr);
|
||||
member.links.target = member;
|
||||
members.set(member.escapedName, member);
|
||||
});
|
||||
const type = createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray);
|
||||
type.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.NonInferrableType;
|
||||
links.resolvedType = type;
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function isGlobalSymbolConstructor(node: Node) {
|
||||
const symbol = getSymbolOfNode(node);
|
||||
const globalSymbol = getGlobalESSymbolConstructorTypeSymbol(/*reportErrors*/ false);
|
||||
@ -16417,6 +16440,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return (deferredGlobalImportCallOptionsType ||= getGlobalType("ImportCallOptions" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
}
|
||||
|
||||
function getGlobalImportAttributesType(reportErrors: boolean) {
|
||||
return (deferredGlobalImportAttributesType ||= getGlobalType("ImportAttributes" as __String, /*arity*/ 0, reportErrors)) || emptyObjectType;
|
||||
}
|
||||
|
||||
function getGlobalESSymbolConstructorSymbol(reportErrors: boolean): Symbol | undefined {
|
||||
return deferredGlobalESSymbolConstructorSymbol ||= getGlobalValueSymbol("Symbol" as __String, reportErrors);
|
||||
}
|
||||
@ -30904,6 +30931,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return getContextualJsxElementAttributesType(parent as JsxOpeningLikeElement, contextFlags);
|
||||
case SyntaxKind.ImportAttribute:
|
||||
return getContextualImportAttributeType(parent as ImportAttribute);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@ -30950,6 +30979,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function getContextualImportAttributeType(node: ImportAttribute) {
|
||||
return getTypeOfPropertyOfContextualType(getGlobalImportAttributesType(/*reportErrors*/ false), getNameFromImportAttribute(node));
|
||||
}
|
||||
|
||||
function getContextualJsxElementAttributesType(node: JsxOpeningLikeElement, contextFlags: ContextFlags | undefined) {
|
||||
if (isJsxOpeningElement(node) && contextFlags !== ContextFlags.Completions) {
|
||||
const index = findContextualNode(node.parent, /*includeCaches*/ !contextFlags);
|
||||
@ -45991,6 +46024,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function checkImportAttributes(declaration: ImportDeclaration | ExportDeclaration) {
|
||||
const node = declaration.attributes;
|
||||
if (node) {
|
||||
const importAttributesType = getGlobalImportAttributesType(/*reportErrors*/ true);
|
||||
if (importAttributesType !== emptyObjectType) {
|
||||
checkTypeAssignableTo(getTypeFromImportAttributes(node), getNullableType(importAttributesType, TypeFlags.Undefined), node);
|
||||
}
|
||||
|
||||
const validForTypeAttributes = isExclusivelyTypeOnlyImportOrExport(declaration);
|
||||
const override = getResolutionModeOverride(node, validForTypeAttributes ? grammarErrorOnNode : undefined);
|
||||
const isImportAttributes = declaration.attributes.token === SyntaxKind.WithKeyword;
|
||||
@ -46020,6 +46058,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function checkImportAttribute(node: ImportAttribute) {
|
||||
return getRegularTypeOfLiteralType(checkExpressionCached(node.value));
|
||||
}
|
||||
|
||||
function checkImportDeclaration(node: ImportDeclaration) {
|
||||
if (checkGrammarModuleElementContext(node, isInJSFile(node) ? Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_module : Diagnostics.An_import_declaration_can_only_be_used_at_the_top_level_of_a_namespace_or_module)) {
|
||||
// If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
|
||||
@ -47700,6 +47742,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return checkMetaPropertyKeyword(node.parent);
|
||||
}
|
||||
|
||||
if (isImportAttributes(node)) {
|
||||
return getGlobalImportAttributesType(/*reportErrors*/ false);
|
||||
}
|
||||
|
||||
return errorType;
|
||||
}
|
||||
|
||||
|
||||
@ -5971,6 +5971,7 @@ export const enum InternalSymbolName {
|
||||
Default = "default", // Default export symbol (technically not wholly internal, but included here for usability)
|
||||
This = "this",
|
||||
InstantiationExpression = "__instantiationExpression", // Instantiation expressions
|
||||
ImportAttributes = "__importAttributes",
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -220,6 +220,7 @@ import {
|
||||
idText,
|
||||
IfStatement,
|
||||
ignoredPaths,
|
||||
ImportAttribute,
|
||||
ImportCall,
|
||||
ImportClause,
|
||||
ImportDeclaration,
|
||||
@ -10656,3 +10657,8 @@ export function replaceFirstStar(s: string, replacement: string): string {
|
||||
// Attempt to defeat this analysis by indirectly calling the method.
|
||||
return stringReplace.call(s, "*", replacement);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getNameFromImportAttribute(node: ImportAttribute) {
|
||||
return isIdentifier(node.name) ? node.name.escapedText : escapeLeadingUnderscores(node.name.text);
|
||||
}
|
||||
|
||||
@ -2448,7 +2448,13 @@ export class TestState {
|
||||
const annotations = this.annotateContentWithTooltips(
|
||||
result,
|
||||
"completions",
|
||||
item => item.optionalReplacementSpan,
|
||||
item => {
|
||||
if (item.optionalReplacementSpan) {
|
||||
const { start, length } = item.optionalReplacementSpan;
|
||||
return start && length === 0 ? { start, length: 1 } : item.optionalReplacementSpan;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
item =>
|
||||
item.entries?.flatMap(
|
||||
entry =>
|
||||
|
||||
@ -95,6 +95,7 @@ import {
|
||||
getLineStartPositionForPosition,
|
||||
getLocalSymbolForExportDefault,
|
||||
getModifiers,
|
||||
getNameFromImportAttribute,
|
||||
getNameOfDeclaration,
|
||||
getNameTable,
|
||||
getNewLineCharacter,
|
||||
@ -169,6 +170,7 @@ import {
|
||||
isIdentifier,
|
||||
isIdentifierText,
|
||||
isImportableFile,
|
||||
isImportAttributes,
|
||||
isImportDeclaration,
|
||||
isImportEqualsDeclaration,
|
||||
isImportKeyword,
|
||||
@ -3768,6 +3770,7 @@ function getCompletionData(
|
||||
|| tryGetObjectLikeCompletionSymbols()
|
||||
|| tryGetImportCompletionSymbols()
|
||||
|| tryGetImportOrExportClauseCompletionSymbols()
|
||||
|| tryGetImportAttributesCompletionSymbols()
|
||||
|| tryGetLocalNamedExportCompletionSymbols()
|
||||
|| tryGetConstructorCompletion()
|
||||
|| tryGetClassLikeCompletionSymbols()
|
||||
@ -4455,6 +4458,21 @@ function getCompletionData(
|
||||
return GlobalsSearch.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* import { x } from "foo" with { | }
|
||||
*/
|
||||
function tryGetImportAttributesCompletionSymbols(): GlobalsSearch {
|
||||
if (contextToken === undefined) return GlobalsSearch.Continue;
|
||||
|
||||
const importAttributes = contextToken.kind === SyntaxKind.OpenBraceToken || contextToken.kind === SyntaxKind.CommaToken ? tryCast(contextToken.parent, isImportAttributes) :
|
||||
contextToken.kind === SyntaxKind.ColonToken ? tryCast(contextToken.parent.parent, isImportAttributes) : undefined;
|
||||
if (importAttributes === undefined) return GlobalsSearch.Continue;
|
||||
|
||||
const existing = new Set(importAttributes.elements.map(getNameFromImportAttribute));
|
||||
symbols = filter(typeChecker.getTypeAtLocation(importAttributes).getApparentProperties(), attr => !existing.has(attr.escapedName));
|
||||
return GlobalsSearch.Success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds local declarations for completions in named exports:
|
||||
*
|
||||
|
||||
@ -7076,6 +7076,7 @@ declare namespace ts {
|
||||
Default = "default",
|
||||
This = "this",
|
||||
InstantiationExpression = "__instantiationExpression",
|
||||
ImportAttributes = "__importAttributes",
|
||||
}
|
||||
/**
|
||||
* This represents a string whose leading underscore have been escaped by adding extra leading underscores.
|
||||
|
||||
@ -0,0 +1,334 @@
|
||||
// === Completions ===
|
||||
=== /tests/cases/fourslash/./b.ts ===
|
||||
// declare global {
|
||||
// interface ImportAttributes {
|
||||
// type: "json",
|
||||
// "resolution-mode": "import"
|
||||
// }
|
||||
// }
|
||||
// const str = "hello";
|
||||
//
|
||||
// import * as t1 from "./a" with { };
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | (property) ImportAttributes["resolution-mode"]: "import"
|
||||
// | (property) ImportAttributes.type: "json"
|
||||
// | ----------------------------------------------------------------------
|
||||
// import * as t2 from "./a" with { type: "" };
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | json
|
||||
// | ----------------------------------------------------------------------
|
||||
// import * as t3 from "./a" with { type: "json", };
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | (property) ImportAttributes["resolution-mode"]: "import"
|
||||
// | ----------------------------------------------------------------------
|
||||
// import * as t4 from "./a" with { type: };
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | "json"
|
||||
// | (property) ImportAttributes["resolution-mode"]: "import"
|
||||
// | ----------------------------------------------------------------------
|
||||
|
||||
[
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/./b.ts",
|
||||
"position": 171,
|
||||
"name": "1"
|
||||
},
|
||||
"item": {
|
||||
"flags": 0,
|
||||
"isGlobalCompletion": false,
|
||||
"isMemberCompletion": false,
|
||||
"isNewIdentifierLocation": false,
|
||||
"entries": [
|
||||
{
|
||||
"name": "resolution-mode",
|
||||
"kind": "property",
|
||||
"kindModifiers": "declare",
|
||||
"sortText": "11",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "property",
|
||||
"kind": "text"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "ImportAttributes",
|
||||
"kind": "interfaceName"
|
||||
},
|
||||
{
|
||||
"text": "[",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "\"resolution-mode\"",
|
||||
"kind": "stringLiteral"
|
||||
},
|
||||
{
|
||||
"text": "]",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "\"import\"",
|
||||
"kind": "stringLiteral"
|
||||
}
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"kind": "property",
|
||||
"kindModifiers": "declare",
|
||||
"sortText": "11",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "property",
|
||||
"kind": "text"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "ImportAttributes",
|
||||
"kind": "interfaceName"
|
||||
},
|
||||
{
|
||||
"text": ".",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "type",
|
||||
"kind": "propertyName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "\"json\"",
|
||||
"kind": "stringLiteral"
|
||||
}
|
||||
],
|
||||
"documentation": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/./b.ts",
|
||||
"position": 215,
|
||||
"name": "2"
|
||||
},
|
||||
"item": {
|
||||
"isGlobalCompletion": false,
|
||||
"isMemberCompletion": false,
|
||||
"isNewIdentifierLocation": false,
|
||||
"optionalReplacementSpan": {
|
||||
"start": 215,
|
||||
"length": 0
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"name": "json",
|
||||
"kindModifiers": "",
|
||||
"kind": "string",
|
||||
"sortText": "11",
|
||||
"replacementSpan": {
|
||||
"start": 215,
|
||||
"length": 0
|
||||
},
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "json",
|
||||
"kind": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/./b.ts",
|
||||
"position": 267,
|
||||
"name": "3"
|
||||
},
|
||||
"item": {
|
||||
"flags": 0,
|
||||
"isGlobalCompletion": false,
|
||||
"isMemberCompletion": false,
|
||||
"isNewIdentifierLocation": false,
|
||||
"entries": [
|
||||
{
|
||||
"name": "resolution-mode",
|
||||
"kind": "property",
|
||||
"kindModifiers": "declare",
|
||||
"sortText": "11",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "property",
|
||||
"kind": "text"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "ImportAttributes",
|
||||
"kind": "interfaceName"
|
||||
},
|
||||
{
|
||||
"text": "[",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "\"resolution-mode\"",
|
||||
"kind": "stringLiteral"
|
||||
},
|
||||
{
|
||||
"text": "]",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "\"import\"",
|
||||
"kind": "stringLiteral"
|
||||
}
|
||||
],
|
||||
"documentation": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/./b.ts",
|
||||
"position": 310,
|
||||
"name": "4"
|
||||
},
|
||||
"item": {
|
||||
"flags": 0,
|
||||
"isGlobalCompletion": false,
|
||||
"isMemberCompletion": false,
|
||||
"isNewIdentifierLocation": false,
|
||||
"entries": [
|
||||
{
|
||||
"name": "\"json\"",
|
||||
"kind": "string",
|
||||
"kindModifiers": "",
|
||||
"sortText": "11",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "\"json\"",
|
||||
"kind": "stringLiteral"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "resolution-mode",
|
||||
"kind": "property",
|
||||
"kindModifiers": "declare",
|
||||
"sortText": "11",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "property",
|
||||
"kind": "text"
|
||||
},
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "ImportAttributes",
|
||||
"kind": "interfaceName"
|
||||
},
|
||||
{
|
||||
"text": "[",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": "\"resolution-mode\"",
|
||||
"kind": "stringLiteral"
|
||||
},
|
||||
{
|
||||
"text": "]",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "\"import\"",
|
||||
"kind": "stringLiteral"
|
||||
}
|
||||
],
|
||||
"documentation": []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -17,7 +17,7 @@
|
||||
// createStyles({
|
||||
// x: {
|
||||
// '': ''
|
||||
//
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | (property) alignContent?: string
|
||||
// | (property) alignItems?: string
|
||||
|
||||
@ -1,13 +1,29 @@
|
||||
mod.mts(1,37): error TS2322: Type '{ field: 0; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
mod.mts(1,52): error TS2837: Import assertion values must be string literal expressions.
|
||||
mod.mts(3,52): error TS2837: Import assertion values must be string literal expressions.
|
||||
mod.mts(5,37): error TS2322: Type '{ field: RegExp; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type 'RegExp' is not assignable to type 'string'.
|
||||
mod.mts(5,52): error TS2837: Import assertion values must be string literal expressions.
|
||||
mod.mts(7,37): error TS2322: Type '{ field: string[]; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type 'string[]' is not assignable to type 'string'.
|
||||
mod.mts(7,52): error TS2837: Import assertion values must be string literal expressions.
|
||||
mod.mts(9,37): error TS2322: Type '{ field: { a: number; }; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type '{ a: number; }' is not assignable to type 'string'.
|
||||
mod.mts(9,52): error TS2837: Import assertion values must be string literal expressions.
|
||||
mod.mts(11,66): error TS2837: Import assertion values must be string literal expressions.
|
||||
|
||||
|
||||
==== mod.mts (6 errors) ====
|
||||
==== mod.mts (10 errors) ====
|
||||
import * as thing1 from "./mod.mjs" assert {field: 0};
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: 0; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
~
|
||||
!!! error TS2837: Import assertion values must be string literal expressions.
|
||||
|
||||
@ -16,14 +32,26 @@ mod.mts(11,66): error TS2837: Import assertion values must be string literal exp
|
||||
!!! error TS2837: Import assertion values must be string literal expressions.
|
||||
|
||||
import * as thing3 from "./mod.mjs" assert {field: /a/g};
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: RegExp; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'RegExp' is not assignable to type 'string'.
|
||||
~~~~
|
||||
!!! error TS2837: Import assertion values must be string literal expressions.
|
||||
|
||||
import * as thing4 from "./mod.mjs" assert {field: ["a"]};
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: string[]; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'string[]' is not assignable to type 'string'.
|
||||
~~~~~
|
||||
!!! error TS2837: Import assertion values must be string literal expressions.
|
||||
|
||||
import * as thing5 from "./mod.mjs" assert {field: { a: 0 }};
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: { a: number; }; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type '{ a: number; }' is not assignable to type 'string'.
|
||||
~~~~~~~~
|
||||
!!! error TS2837: Import assertion values must be string literal expressions.
|
||||
|
||||
|
||||
@ -1,25 +1,53 @@
|
||||
mod.mts(1,37): error TS2322: Type '{ field: 0; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
mod.mts(1,51): error TS2858: Import attribute values must be string literal expressions.
|
||||
mod.mts(2,51): error TS2858: Import attribute values must be string literal expressions.
|
||||
mod.mts(3,37): error TS2322: Type '{ field: RegExp; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type 'RegExp' is not assignable to type 'string'.
|
||||
mod.mts(3,51): error TS2858: Import attribute values must be string literal expressions.
|
||||
mod.mts(4,37): error TS2322: Type '{ field: string[]; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type 'string[]' is not assignable to type 'string'.
|
||||
mod.mts(4,51): error TS2858: Import attribute values must be string literal expressions.
|
||||
mod.mts(5,37): error TS2322: Type '{ field: { a: number; }; }' is not assignable to type 'ImportAttributes'.
|
||||
Property 'field' is incompatible with index signature.
|
||||
Type '{ a: number; }' is not assignable to type 'string'.
|
||||
mod.mts(5,51): error TS2858: Import attribute values must be string literal expressions.
|
||||
mod.mts(6,65): error TS2858: Import attribute values must be string literal expressions.
|
||||
|
||||
|
||||
==== mod.mts (6 errors) ====
|
||||
==== mod.mts (10 errors) ====
|
||||
import * as thing1 from "./mod.mjs" with { field: 0 };
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: 0; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
~
|
||||
!!! error TS2858: Import attribute values must be string literal expressions.
|
||||
import * as thing2 from "./mod.mjs" with { field: `a` };
|
||||
~~~
|
||||
!!! error TS2858: Import attribute values must be string literal expressions.
|
||||
import * as thing3 from "./mod.mjs" with { field: /a/g };
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: RegExp; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'RegExp' is not assignable to type 'string'.
|
||||
~~~~
|
||||
!!! error TS2858: Import attribute values must be string literal expressions.
|
||||
import * as thing4 from "./mod.mjs" with { field: ["a"] };
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: string[]; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type 'string[]' is not assignable to type 'string'.
|
||||
~~~~~
|
||||
!!! error TS2858: Import attribute values must be string literal expressions.
|
||||
import * as thing5 from "./mod.mjs" with { field: { a: 0 } };
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ field: { a: number; }; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Property 'field' is incompatible with index signature.
|
||||
!!! error TS2322: Type '{ a: number; }' is not assignable to type 'string'.
|
||||
~~~~~~~~
|
||||
!!! error TS2858: Import attribute values must be string literal expressions.
|
||||
import * as thing6 from "./mod.mjs" with { type: "json", field: 0..toString() };
|
||||
|
||||
41
tests/baselines/reference/importAttributes9.errors.txt
Normal file
41
tests/baselines/reference/importAttributes9.errors.txt
Normal file
@ -0,0 +1,41 @@
|
||||
b.ts(7,27): error TS2322: Type '{ type: "not-json"; }' is not assignable to type 'ImportAttributes'.
|
||||
Types of property 'type' are incompatible.
|
||||
Type '"not-json"' is not assignable to type '"json"'.
|
||||
b.ts(11,25): error TS2322: Type '{ with: { type: "not-json"; }; }' is not assignable to type 'ImportCallOptions'.
|
||||
The types of 'with.type' are incompatible between these types.
|
||||
Type '"not-json"' is not assignable to type '"json"'.
|
||||
|
||||
|
||||
==== ./a.ts (0 errors) ====
|
||||
export default {};
|
||||
|
||||
==== ./b.ts (2 errors) ====
|
||||
declare global {
|
||||
interface ImportAttributes {
|
||||
type: "json"
|
||||
}
|
||||
}
|
||||
|
||||
import * as ns from "./a" with { type: "not-json" };
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ type: "not-json"; }' is not assignable to type 'ImportAttributes'.
|
||||
!!! error TS2322: Types of property 'type' are incompatible.
|
||||
!!! error TS2322: Type '"not-json"' is not assignable to type '"json"'.
|
||||
void ns;
|
||||
|
||||
async function f() {
|
||||
await import("./a", {
|
||||
~
|
||||
with: {
|
||||
~~~~~~~~~~~~~~~
|
||||
type: "not-json",
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
},
|
||||
~~~~~~~~~~
|
||||
});
|
||||
~~~~~
|
||||
!!! error TS2322: Type '{ with: { type: "not-json"; }; }' is not assignable to type 'ImportCallOptions'.
|
||||
!!! error TS2322: The types of 'with.type' are incompatible between these types.
|
||||
!!! error TS2322: Type '"not-json"' is not assignable to type '"json"'.
|
||||
}
|
||||
|
||||
36
tests/baselines/reference/importAttributes9.js
Normal file
36
tests/baselines/reference/importAttributes9.js
Normal file
@ -0,0 +1,36 @@
|
||||
//// [tests/cases/conformance/importAttributes/importAttributes9.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
export default {};
|
||||
|
||||
//// [b.ts]
|
||||
declare global {
|
||||
interface ImportAttributes {
|
||||
type: "json"
|
||||
}
|
||||
}
|
||||
|
||||
import * as ns from "./a" with { type: "not-json" };
|
||||
void ns;
|
||||
|
||||
async function f() {
|
||||
await import("./a", {
|
||||
with: {
|
||||
type: "not-json",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//// [a.js]
|
||||
export default {};
|
||||
//// [b.js]
|
||||
import * as ns from "./a" with { type: "not-json" };
|
||||
void ns;
|
||||
async function f() {
|
||||
await import("./a", {
|
||||
with: {
|
||||
type: "not-json",
|
||||
},
|
||||
});
|
||||
}
|
||||
40
tests/baselines/reference/importAttributes9.symbols
Normal file
40
tests/baselines/reference/importAttributes9.symbols
Normal file
@ -0,0 +1,40 @@
|
||||
//// [tests/cases/conformance/importAttributes/importAttributes9.ts] ////
|
||||
|
||||
=== ./a.ts ===
|
||||
|
||||
export default {};
|
||||
|
||||
=== ./b.ts ===
|
||||
declare global {
|
||||
>global : Symbol(global, Decl(b.ts, 0, 0))
|
||||
|
||||
interface ImportAttributes {
|
||||
>ImportAttributes : Symbol(ImportAttributes, Decl(lib.es5.d.ts, --, --), Decl(b.ts, 0, 16))
|
||||
|
||||
type: "json"
|
||||
>type : Symbol(ImportAttributes.type, Decl(b.ts, 1, 33))
|
||||
}
|
||||
}
|
||||
|
||||
import * as ns from "./a" with { type: "not-json" };
|
||||
>ns : Symbol(ns, Decl(b.ts, 6, 6))
|
||||
|
||||
void ns;
|
||||
>ns : Symbol(ns, Decl(b.ts, 6, 6))
|
||||
|
||||
async function f() {
|
||||
>f : Symbol(f, Decl(b.ts, 7, 8))
|
||||
|
||||
await import("./a", {
|
||||
>"./a" : Symbol(ns, Decl(a.ts, 0, 0))
|
||||
|
||||
with: {
|
||||
>with : Symbol(with, Decl(b.ts, 10, 25))
|
||||
|
||||
type: "not-json",
|
||||
>type : Symbol(type, Decl(b.ts, 11, 15))
|
||||
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
45
tests/baselines/reference/importAttributes9.types
Normal file
45
tests/baselines/reference/importAttributes9.types
Normal file
@ -0,0 +1,45 @@
|
||||
//// [tests/cases/conformance/importAttributes/importAttributes9.ts] ////
|
||||
|
||||
=== ./a.ts ===
|
||||
export default {};
|
||||
>{} : {}
|
||||
|
||||
=== ./b.ts ===
|
||||
declare global {
|
||||
>global : any
|
||||
|
||||
interface ImportAttributes {
|
||||
type: "json"
|
||||
>type : "json"
|
||||
}
|
||||
}
|
||||
|
||||
import * as ns from "./a" with { type: "not-json" };
|
||||
>ns : typeof ns
|
||||
>type : any
|
||||
|
||||
void ns;
|
||||
>void ns : undefined
|
||||
>ns : typeof ns
|
||||
|
||||
async function f() {
|
||||
>f : () => Promise<void>
|
||||
|
||||
await import("./a", {
|
||||
>await import("./a", { with: { type: "not-json", }, }) : typeof ns
|
||||
>import("./a", { with: { type: "not-json", }, }) : Promise<typeof ns>
|
||||
>"./a" : "./a"
|
||||
>{ with: { type: "not-json", }, } : { with: { type: "not-json"; }; }
|
||||
|
||||
with: {
|
||||
>with : { type: "not-json"; }
|
||||
>{ type: "not-json", } : { type: "not-json"; }
|
||||
|
||||
type: "not-json",
|
||||
>type : "not-json"
|
||||
>"not-json" : "not-json"
|
||||
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
// @module: esnext
|
||||
// @target: esnext
|
||||
// @filename: ./a.ts
|
||||
export default {};
|
||||
|
||||
// @filename: ./b.ts
|
||||
declare global {
|
||||
interface ImportAttributes {
|
||||
type: "json"
|
||||
}
|
||||
}
|
||||
|
||||
import * as ns from "./a" with { type: "not-json" };
|
||||
void ns;
|
||||
|
||||
async function f() {
|
||||
await import("./a", {
|
||||
with: {
|
||||
type: "not-json",
|
||||
},
|
||||
});
|
||||
}
|
||||
22
tests/cases/fourslash/completionListForImportAttributes.ts
Normal file
22
tests/cases/fourslash/completionListForImportAttributes.ts
Normal file
@ -0,0 +1,22 @@
|
||||
///<reference path="fourslash.ts" />
|
||||
|
||||
// @module: esnext
|
||||
// @target: esnext
|
||||
// @filename: ./a.ts
|
||||
////export default {};
|
||||
|
||||
// @filename: ./b.ts
|
||||
////declare global {
|
||||
//// interface ImportAttributes {
|
||||
//// type: "json",
|
||||
//// "resolution-mode": "import"
|
||||
//// }
|
||||
////}
|
||||
////const str = "hello";
|
||||
////
|
||||
////import * as t1 from "./a" with { /*1*/ };
|
||||
////import * as t2 from "./a" with { type: "/*2*/" };
|
||||
////import * as t3 from "./a" with { type: "json", /*3*/ };
|
||||
////import * as t4 from "./a" with { type: /*4*/ };
|
||||
|
||||
verify.baselineCompletions();
|
||||
Loading…
x
Reference in New Issue
Block a user