#Access Record<string,string> with square brackets [] safely

71 messages ยท Page 1 of 1 (latest)

magic crow
#

Trying to access a record with brackets

export interface RecordValue {
    value: string
}

export const TestRecords: Record<string, RecordValue> = {
    Test0: { value: 'TestValue0' },
    Test1: { value: 'TestValue1' },
    Test2: { value: 'TestValue2' },
}

const foo = (string: string): void => {
// eslint-disable-next-line no-unused-expressions
    TestRecords[string].value
}

How to I do this without disabling eslint-disable-next-line no-unused-expressions

magic crow
#

Access Record<string,string> with square brackets [] safely

silent cedar
#

by using it

#

you're getting that value out, you just aren't doing anything with the result. this isn't related to safety

magic crow
#

It works but I don't want to have to disable the linter rule

silent cedar
#

you don't have to disable it

#

just use that expression

eager lotus
#

The problem with Record<string, T> is you're saying it can have any string key. This means the compiler will allow TestRecords["foo"] even tho foo is not a key in TestRecords

If you want to access it safely, either don't declare it as a Record, or declare the keys explicitly,

// example 1
export const TestRecords = {
    Test0: { value: 'TestValue0' },
    Test1: { value: 'TestValue1' },
    Test2: { value: 'TestValue2' },
}

const foo = (key: keyof typeof TestRecords): string => {
    return TestRecords[key].value
}
// example 2
type TestRecordKeys = "Test0" | "Test1" | "Test2";
export const TestRecords: Record<TestRecordKeys, RecordValue> = {
    Test0: { value: 'TestValue0' },
    Test1: { value: 'TestValue1' },
    Test2: { value: 'TestValue2' },
}

const foo = (key: TestRecordKeys): string => {
    return TestRecords[key].value
}
lone oxide
#

@eager lotus You can turn on noUncheckedIndexedAccess and it fixes that issue without needing to avoid Record.

#

Sometimes you really do want Record<string, Type> because you don't have a known list of keys, unlike both of your examples.

magic crow
#

Thanks. Work in company of one and never done either javascript or typescript so been challenging. We'll doing it right.

silent cedar
#

have you done other languages before?

magic crow
#

Lots, rust, c++, cobol, assembley, java, c#... Someone put this warning in the linter with forethought one would hope and reading the explanation made sence, so want to fix properly. Again thanks, I believe twice now for me, for answering.

magic crow
#

Hi, Tried the suggestion and still getting error

#
export const TestRecords: Record<string, RecordValue> = {
    Test0: { value: 'TestValue0' },
    Test1: { value: 'TestValue1' },
    Test2: { value: 'TestValue2' },
}

const foo = (test: keyof typeof BRATPages): void => {
    const a = TestRecords[test].value
}
#

And with approach 2

#
type TestRecordKeys = 'Test0' | 'Test1' | 'Test2'

export const TestRecords: Record<TestRecordKeys, RecordValue> = {
    Test0: { value: 'TestValue0' },
    Test1: { value: 'TestValue1' },
    Test2: { value: 'TestValue2' },
}

const foo = (test: TestRecordKeys): void => {
    const a = TestRecords[test].value
}
lone oxide
#

Not familiar with whatever lint rule that is, you might need to look at theird coumentation for why they think that's a problem

magic crow
#

I think it basically says no [] without constructor so for numbers you can do Number(myKey), for String you can do String(myKey). Just not sure how to do a keyof

silent cedar
#

i don't think that's relevant

magic crow
silent cedar
#

no [] without constructor
this doesn't really make sense

lone oxide
#

Yeah, this seems pretty odd.

silent cedar
magic crow
#

Well is the thing was a number you could do

const a = TestRecords[Number(test)].value
silent cedar
#

that rule just says, no dynamic property access.

lone oxide
#

JS already coerces object lookups to strings, so wrapping it in String(test) wouldn't do anything anyway.

magic crow
#

yes. IT english not great but basically yes

#

No, didnt't write the rules, just been asked to follow them

silent cedar
lone oxide
#

[technicallycorrect.gif]

silent cedar
magic crow
#

They hired someone for the code review Sigh!

#

Been running a year

silent cedar
#

i mustve misunderstood that earlier comment then

magic crow
#

No third-party

#

just me, on my lonesome

silent cedar
#

...so are you working alone or not?

muted pecanBOT
#

@eager lotus Here's a shortened URL of your playground link! You can remove the full link from your message.

jamesfoster#0

Preview:```ts
// example 1
{
const TestRecords = {
Test0: { value: 'TestValue0' },
Test1: { value: 'TestValue1' },
Test2: { value: 'TestValue2' },
}

const foo = (key: keyof typeof TestRecords): string => {
return TestRecords[key].value
}
}

// example 2
...```

lone oxide
#

Well, if you must follow this lint rule, I'm think the only fix here is:

type TestRecordKeys = "Test0" | "Test1" | "Test2";
export const TestRecords: Record<TestRecordKeys, RecordValue> = {
    Test0: { value: 'TestValue0' },
    Test1: { value: 'TestValue1' },
    Test2: { value: 'TestValue2' },
}

const foo = (key: TestRecordKeys): string => {
    if(key === "Test0") return TestRecords.Test0;
    if(key === "Test1") return TestRecords.Test1;
    if(key === "Test2") return TestRecords.Test2;
    let _: never = key; // Check that you've handled all the cases
    throw new Error("Missed one");
}
magic crow
#

Yes alone. They had a third-party review

#

switch and never?

lone oxide
#

Or switch, yeah, if you prefer that syntax.

eager lotus
#

you can also use key satisfies never

magic crow
#

As my skills get better ๐Ÿ™‚

silent cedar
#

if you're just practicing/learning, you should probably disable security altogether

#

that's for application/production level stuff

#

ts itself and eslint & ts-eslint will be fine

lone oxide
#

Honestly... wouldn't turn this one on even for production

magic crow
#

My humble view, is behind a VPN, Azure and OAuth 2.0 and running in a container with no external access, I think they are pretty safe

silent cedar
#

it's not for that aspect

#

oh wait you're the guy that asked about detect-unsafe-regex too!

magic crow
#

Indeed

#

Perhaps you can see my world!

silent cedar
magic crow
#

They should make a song

silent cedar
lone oxide
#

Can't have security issues if you can't write code at all.

magic crow
#

They problem is a bigger one. I have no reverant power as I am new to typescript. And they just hear, security, turn off with literally no knowledge of IT at all.

silent cedar
#

this is even in their readme

This project will help identify potential security hotspots, but finds a lot of false positives which need triage by a human.
emphasis mine

#

it flags equality operators jesus

#

and dynamic imports???

magic crow
#

I will give it some blarney and hope

#

I think you would need to be quite advanced to provide feedback about rules to discard them. Most are obvious and make sense

silent cedar
#

you'd need to be quite advanced to justify/reason with these rules tbh

magic crow
#

Thanks, slowly feeling better ๐Ÿ™‚

silent cedar
#

like i said before, these rules are really paranoid. and they're mostly for guarding against malicious user input or source manipulation, which tbh for the latter you have bigger problems

#

your original code for types and access was fine tbh. the different types proposed aren't better, they're just for different situations.

magic crow
#

Thanks again will disable with comment.