英文:
Use key value to look up variable when doing import as namespace
问题
I understand your request, here's the translated content:
也许我正在尝试的操作是不可能的,或者我采用了错误的方法,但是否可以使用字符串来在导入的命名空间上进行查找?
如果我有一个文件:my_file.ts
,其内容如下所示:
export const MyThing: CustomType = {
propertyOne: "name",
propertyTwo: 2
}
export const AnotherThing: CustomType = {
propertyOne: "Another",
propertyTwo: 3
}
然后我有一个文件要导入所有这些内容,但需要根据一个字符串动态查找并使用它们:
import * as allthings from "dir/folder/my_file";
function doStuff() {
let currentThing = allthings['MyThing']; // 可行
let name = 'MyThing';
let currentThing2 = allthings[name]; // 无法使用
}
这里出现的错误是:
元素隐式具有“any”类型,因为类型为“string”的表达式不能用于索引类型为“typeof import("dir/folder/my_file")”的类型。在类型“typeof import("dir/folder/my_file")”上找不到具有参数类型“string”的索引签名。
为什么字面字符串有效,而类型为字符串的变量无法使用呢?
英文:
Perhaps what I'm asking to do is impossible, or I'm taking the wrong approach but is it possible to use a string to do a lookup on an imported namespace?
If I have a file: my_file.ts
and its contents are many of these:
export const MyThing: CustomType = {
propertyOne: "name",
propertyTwo: 2
}
export const AnotherThing: CustomType = {
propertyOne: "Another",
propertyTwo: 3
}
Then I have a file that is going to import all these, but needs to find and use them dynamically based on a string:
import * as allthings from "dir/folder/my_file"
function doStuff() {
let currentThing = allthings['MyThing']; // works
let name = 'MyThing';
let currentThing2 = allthings[name]; // doesnt work
}
The error I get here is:
> Element implicitly has an 'any' type because expression of type
> 'string' can't be used to index type 'typeof
> import("dir/folder/my_file")'. No index signature with a parameter of
> type 'string' was found on type 'typeof import("dir/folder/my_file")'.
Why does the literal string work but not a variable of type string?
答案1
得分: 3
The literal string doesn't work because someone could reassign any string to your let name
variable.
如果使用字面字符串,由于任何人都可以重新分配任何字符串给你的 let name
变量,所以它不起作用。
It will work if your string is const
. Casting it is possible:
如果你的字符串是 const
,它将起作用。也可以进行强制转换:
let name = 'MyThing' as const;
But you should just define a const
variable which has the same effect. There's no reason to define a variable with let
unless you intend to change it.
但是你应该只定义一个具有相同效果的 const
变量。除非你打算更改它,否则没有理由使用 let
来定义变量。
const name = 'MyThing';
See this TS playground example
如果你不知道键值提前,那么如果 my_file
中的所有对象都是相同类型(CustomType
),那么你可以安全地使用 keyof typeof allthings
作为类型。
For these enum-like objects, you can use satisfies Record<string, MyType>
to enforce they are all of the same type.
对于这些类似枚举的对象,你可以使用 satisfies Record<string, MyType>
来强制它们都是相同类型的。
英文:
The literal string doesn't work because someone could reassign any string to your let name
variable.
It will work if your string is const
. Casting it is possible:
let name = 'MyThing' as const;
But you should just define a const
variable which has the same effect. There's no reason to define a variable with let
unless you intend to change it.
const name = 'MyThing';
See this TS playground example
If you don't know the key ahead of time, then if all the objects in my_file
are of the same type (CustomType
), then you can safely use keyof typeof allthings
as the type
export const allthings = {
MyThing: {
propertyOne: "name",
propertyTwo: 2
},
AnotherThing: {
propertyOne: "Another",
propertyTwo: 3
}
};
type CustomType = typeof allthings[keyof typeof allthings];
function getValue(key: keyof typeof allthings): CustomType {
return allthings[key];
}
See TS example
For these enum like objects, you can use satisfies Record<string, MyType>
to enforce they are all of the same type
interface CustomType {
propertyOne: string,
propertyTwo: number
}
const allthings = {
MyThing: {
propertyOne: "name",
propertyTwo: 2
},
AnotherThing: {
propertyOne: "Another",
propertyTwo: 3
}
} satisfies Record<string, CustomType>;
function getValueFromAllThings(key: keyof typeof allthings): CustomType {
return allthings[key];
}
答案2
得分: 0
I reread a similar question here: https://stackoverflow.com/questions/57086672/element-implicitly-has-an-any-type-because-expression-of-type-string-cant-b
And was finally able to get it to work by doing this:
import * as allthings from "dir/folder/my_file";
function doStuff() {
let currentThing = allthings['MyThing']; // works
let name = 'MyThing';
let currentThing2 = allthings[name as keyof typeof allthings]; // does work
}
英文:
I reread a similar question here: https://stackoverflow.com/questions/57086672/element-implicitly-has-an-any-type-because-expression-of-type-string-cant-b
And was finally able to get it to work by doing this:
import * as allthings from "dir/folder/my_file"
function doStuff() {
let currentThing = allthings['MyThing']; // works
let name = 'MyThing';
let currentThing2 = allthings[name as keyof typeof allthings]; // does work
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论